Merge bb-10.2-ext into 10.3

This commit is contained in:
Marko Mäkelä 2017-12-19 17:28:22 +02:00
commit 0436a0ff3c
49 changed files with 866 additions and 299 deletions

View File

@ -1061,11 +1061,13 @@ struct my_option xb_server_options[] =
(G_PTR*) &defaults_group, (G_PTR*) &defaults_group,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"plugin-dir", OPT_PLUGIN_DIR, "Server plugin directory",
{"plugin-dir", OPT_PLUGIN_DIR,
"Server plugin directory. Used to load encryption plugin during 'prepare' phase."
"Has no effect in the 'backup' phase (plugin directory during backup is the same as server's)",
&xb_plugin_dir, &xb_plugin_dir,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{ "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load",
{ "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load during 'prepare' phase.",
&xb_plugin_load, &xb_plugin_load,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
@ -3624,7 +3626,6 @@ fail:
/* Reset the system variables in the recovery module. */
recv_sys_var_init();
trx_pool_init();
row_mysql_init();
ut_crc32_init();
crc_init();

View File

@ -152,6 +152,8 @@ typedef struct my_aio_result {
/* Extra length needed for filename if one calls my_create_backup_name */
#define MY_BACKUP_NAME_EXTRA_LENGTH 17
char *guess_malloc_library();
/* If we have our own safemalloc (for debugging) */
#if defined(SAFEMALLOC)
void sf_report_leaked_memory(my_thread_id id);

View File

@ -82,7 +82,10 @@ call mtr.check_testcase();
let $datadir=`select @@datadir`;
list_files $datadir mysql_upgrade_info;
list_files $datadir/test #sql*;
list_files_write_file $datadir.tempfiles.txt $datadir/test #sql*;
--replace_regex /#sql-ib[0-9a-f]+-[0-9a-f]+\.ibd\n//
cat_file $datadir.tempfiles.txt;
remove_file $datadir.tempfiles.txt;
list_files $datadir/mysql #sql*;
--enable_query_log

View File

@ -115,3 +115,7 @@ c9: 0x000000000101000000000000000000F03F000000000000F03F
#Print the table contents in html format
<TABLE BORDER=1><TR><TH>c1</TH><TH>c2</TH><TH>c3</TH><TH>c4</TH><TH>c5</TH><TH>c6</TH><TH>c7</TH><TH>c8</TH><TH>c9</TH></TR><TR><TD>0x74696E79626C6F622D74657874207265616461626C65</TD><TD>0x626C6F622D74657874207265616461626C65</TD><TD>0x6D656469756D626C6F622D74657874207265616461626C65</TD><TD>0x6C6F6E67626C6F622D74657874207265616461626C65</TD><TD>0x74657874207265616461626C65</TD><TD>0x01</TD><TD>0x63</TD><TD>0x7661726961626C65</TD><TD>0x000000000101000000000000000000F03F000000000000F03F</TD></TR></TABLE><TABLE BORDER=1><TR><TH>id</TH><TH>col1</TH><TH>col2</TH></TR><TR><TD>1</TD><TD>0xAB123400000000000000</TD><TD>0x123ABC</TD></TR><TR><TD>2</TD><TD>0xDE123400000000000000</TD><TD>0x123DEF</TD></TR></TABLE>DROP TABLE t1, t2;
create table t1 (a int);
formatID gtrid_length bqual_length data
1 3 2 0x7472316271
DROP TABLE t1;

View File

@ -2904,6 +2904,53 @@ n
2
3
#
# mdev-14629: a user-defined variable is defined by the recursive CTE
#
set @var=
(
with recursive cte_tab(a) as (
select 1
union
select a+1 from cte_tab
where a<3)
select count(*) from cte_tab
);
select @var;
@var
3
create table t1(a int, b int);
insert into t1 values (3,8),(1,5),(5,7),(7,4),(4,3);
set @var=
(
with recursive summ(a,s) as (
select 1, 0 union
select t1.b, t1.b+summ.s from summ, t1
where summ.a=t1.a)
select s from summ
order by a desc
limit 1
);
select @var;
@var
27
set @var=
(
with recursive
cte_1 as (
select 1
union
select * from cte_2),
cte_2 as (
select * from cte_1
union
select a from t1, cte_2
where t1.a=cte_2.a)
select * from cte_2
limit 1
);
ERROR HY000: Unacceptable mutual recursion with anchored table 'cte_1'
drop table t1;
#
# MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
#
CREATE TEMPORARY TABLE a_tbl (

View File

@ -60,6 +60,59 @@ a
20
disconnect con1;
connection default;
xa start 'tr1';
insert t1 values (40);
xa end 'tr1';
xa prepare 'tr1';
xa recover format='SQL';
formatID gtrid_length bqual_length data
1 3 0 'tr1'
xa rollback 'tr1';
xa start 'tr1', 'bq';
insert t1 values (40);
xa end 'tr1', 'bq';
xa prepare 'tr1', 'bq';
xa recover format='SQL';
formatID gtrid_length bqual_length data
1 3 2 'tr1','bq'
xa rollback 'tr1', 'bq';
xa start 'tr1', 'bq', 3;
insert t1 values (40);
xa end 'tr1', 'bq', 3;
xa prepare 'tr1', 'bq', 3;
xa recover format='SQL';
formatID gtrid_length bqual_length data
3 3 2 'tr1','bq',3
xa rollback 'tr1', 'bq', 3;
xa start 'tr1#$';
insert t1 values (40);
xa end 'tr1#$';
xa prepare 'tr1#$';
xa recover format='SQL';
formatID gtrid_length bqual_length data
1 5 0 X'7472312324'
xa rollback 'tr1#$';
xa start 'tr1#$', 'bq';
insert t1 values (40);
xa end 'tr1#$', 'bq';
xa prepare 'tr1#$', 'bq';
xa recover format='SQL';
formatID gtrid_length bqual_length data
1 5 2 X'7472312324',X'6271'
xa rollback 'tr1#$', 'bq';
xa start 'tr1#$', 'bq', 3;
insert t1 values (40);
xa end 'tr1#$', 'bq', 3;
xa prepare 'tr1#$', 'bq', 3;
xa recover format='RAW';
formatID gtrid_length bqual_length data
3 5 2 tr1#$bq
xa recover format='PLAIN';
ERROR HY000: Unknown XA RECOVER format name: 'PLAIN'
xa recover format='SQL';
formatID gtrid_length bqual_length data
3 5 2 X'7472312324',X'6271',3
xa rollback 'tr1#$', 'bq', 3;
drop table t1;
drop table if exists t1;
create table t1(a int, b int, c varchar(20), primary key(a)) engine = innodb;

View File

@ -44,10 +44,9 @@ SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
ERROR HY000: Lost connection to MySQL server during query
# Restart mysqld after the crash and reconnect.
# Manual *.frm recovery begin.
# Manual recovery end
FLUSH TABLES;
# Drop the orphaned original table.
SELECT * FROM information_schema.innodb_sys_tables
WHERE table_id = ID;
TABLE_ID NAME FLAG N_COLS SPACE FILE_FORMAT ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
# Files in datadir after manual recovery.
t1.frm
t1.ibd
@ -83,11 +82,9 @@ SET DEBUG_DBUG='+d,innodb_alter_commit_crash_before_commit';
ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
ERROR HY000: Lost connection to MySQL server during query
# Startup the server after the crash
# Read and remember the temporary table name
# Manual *.frm recovery begin. The dictionary was not updated
# and the files were not renamed. The rebuilt table
# was left behind on purpose, to faciliate data recovery.
# Manual recovery end
SELECT * FROM information_schema.innodb_sys_tables
WHERE name LIKE 'test/#sql-ib%';
TABLE_ID NAME FLAG N_COLS SPACE FILE_FORMAT ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
# Drop the orphaned rebuilt table.
SHOW TABLES;
Tables_in_test
@ -123,10 +120,10 @@ SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit';
ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE;
ERROR HY000: Lost connection to MySQL server during query
# Restart mysqld after the crash and reconnect.
# Manual *.frm recovery begin.
# Manual recovery end
SELECT * FROM information_schema.innodb_sys_tables
WHERE table_id = ID;
TABLE_ID NAME FLAG N_COLS SPACE FILE_FORMAT ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
FLUSH TABLES;
# Drop the orphaned original table.
# Files in datadir after manual recovery.
t1.frm
t1.ibd

View File

@ -3,7 +3,22 @@ KEY(c1), KEY(c2), KEY(c2,c1),
KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1),
KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1),
KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB;
CREATE TABLE `#mysql50##sql-ib-foo`(a SERIAL) ENGINE=InnoDB;
INSERT INTO t (c1) VALUES (1),(2),(1);
SET DEBUG_DBUG='+d,row_drop_table_add_to_background';
CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
SELECT * from target;
ERROR 42S02: Table 'test.target' doesn't exist
DROP TABLE t;
CREATE TABLE t (a INT) ENGINE=InnoDB;
DROP TABLE t;
DROP TABLE target;
ERROR 42S02: Unknown table 'test.target'
CREATE TABLE target (a INT) ENGINE=InnoDB;
DROP TABLE target;
SELECT * FROM `#mysql50##sql-ib-foo`;
ERROR 42S02: Table 'test.#mysql50##sql-ib-foo' doesn't exist in engine
DROP TABLE `#mysql50##sql-ib-foo`;
Warnings:
Warning 1932 Table 'test.#mysql50##sql-ib-foo' doesn't exist in engine

View File

@ -1351,3 +1351,15 @@ t CREATE TABLE `t` (
KEY `i` (`i`)
) ENGINE=InnoDB AUTO_INCREMENT=401 DEFAULT CHARSET=latin1
DROP TABLE t;
#
# MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())
#
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 (
c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT
) ENGINE=InnoDB AUTO_INCREMENT=10000000000000000000;
INSERT INTO t1 VALUES ();
SELECT * FROM t1;
c1
1e19
DROP TABLE t1;

View File

@ -75,28 +75,22 @@ ALTER TABLE t1 ADD PRIMARY KEY (f2, f1);
--echo # Restart mysqld after the crash and reconnect.
--source include/start_mysqld.inc
let $temp_table_name = `SELECT SUBSTR(name, 6)
FROM information_schema.innodb_sys_tables
WHERE table_id = $orig_table_id`;
--echo # Manual *.frm recovery begin.
--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm
let TABLENAME_INC= $MYSQLTEST_VARDIR/tmp/tablename.inc;
perl;
my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm";
my $t1_frm = "$ENV{'datadir'}/test/t1.frm";
rename($frm_file[0], $t1_frm);
die unless open OUT, ">$ENV{TABLENAME_INC}";
chdir "$ENV{'datadir'}/test";
my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
print OUT 'let $tablename=', $frm_file[0], ';';
close OUT or die;
EOF
source $TABLENAME_INC;
remove_file $TABLENAME_INC;
--echo # Manual recovery end
--replace_result $orig_table_id ID
eval SELECT * FROM information_schema.innodb_sys_tables
WHERE table_id = $orig_table_id;
FLUSH TABLES;
--echo # Drop the orphaned original table.
--disable_query_log
eval DROP TABLE `$temp_table_name`;
--enable_query_log
move_file $datadir/test/$tablename.frm $datadir/test/t1.frm;
--echo # Files in datadir after manual recovery.
--list_files $MYSQLD_DATADIR/test
@ -134,16 +128,9 @@ ALTER TABLE t2 ADD PRIMARY KEY (f2, f1);
--echo # Startup the server after the crash
--source include/start_mysqld.inc
--echo # Read and remember the temporary table name
let $temp_table_name = `SELECT SUBSTRING(name,6)
FROM information_schema.innodb_sys_tables
WHERE name LIKE "test/#sql-ib$orig_table_id%"`;
SELECT * FROM information_schema.innodb_sys_tables
WHERE name LIKE 'test/#sql-ib%';
--echo # Manual *.frm recovery begin. The dictionary was not updated
--echo # and the files were not renamed. The rebuilt table
--echo # was left behind on purpose, to faciliate data recovery.
let TABLENAME_INC= $MYSQLTEST_VARDIR/tmp/tablename.inc;
perl;
die unless open OUT, ">$ENV{TABLENAME_INC}";
chdir "$ENV{'datadir'}/test";
@ -154,8 +141,6 @@ EOF
source $TABLENAME_INC;
remove_file $TABLENAME_INC;
--echo # Manual recovery end
--echo # Drop the orphaned rebuilt table.
--disable_query_log
eval DROP TABLE `#mysql50#$tablename`;
@ -198,28 +183,24 @@ ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE;
--echo # Restart mysqld after the crash and reconnect.
--source include/start_mysqld.inc
let $temp_table_name = `SELECT SUBSTR(name, 6)
FROM information_schema.innodb_sys_tables
WHERE table_id = $orig_table_id`;
--echo # Manual *.frm recovery begin.
--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm
--replace_result $orig_table_id ID
eval SELECT * FROM information_schema.innodb_sys_tables
WHERE table_id = $orig_table_id;
perl;
my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm";
my $t1_frm = "$ENV{'datadir'}/test/t1.frm";
rename($frm_file[0], $t1_frm);
die unless open OUT, ">$ENV{TABLENAME_INC}";
chdir "$ENV{'datadir'}/test";
my @frm_file = map { substr($_, 0, -4) } glob "#sql-*.frm";
print OUT 'let $tablename=', $frm_file[0], ';';
close OUT or die;
EOF
--echo # Manual recovery end
source $TABLENAME_INC;
remove_file $TABLENAME_INC;
move_file $datadir/test/$tablename.frm $datadir/test/t1.frm;
FLUSH TABLES;
--echo # Drop the orphaned original table.
--disable_query_log
eval DROP TABLE `#mysql50#$temp_table_name`;
--enable_query_log
--echo # Files in datadir after manual recovery.
--list_files $MYSQLD_DATADIR/test

View File

@ -9,6 +9,9 @@ KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1),
KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1),
KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB;
CREATE TABLE `#mysql50##sql-ib-foo`(a SERIAL) ENGINE=InnoDB;
INSERT INTO t (c1) VALUES (1),(2),(1);
let $n= 10;
SET DEBUG_DBUG='+d,row_drop_table_add_to_background';
@ -24,7 +27,18 @@ while ($i) {
dec $i;
}
--enable_query_log
--error ER_DUP_ENTRY
CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t;
--error ER_NO_SUCH_TABLE
SELECT * from target;
DROP TABLE t;
--source include/restart_mysqld.inc
CREATE TABLE t (a INT) ENGINE=InnoDB;
DROP TABLE t;
--error ER_BAD_TABLE_ERROR
DROP TABLE target;
CREATE TABLE target (a INT) ENGINE=InnoDB;
DROP TABLE target;
--error ER_NO_SUCH_TABLE_IN_ENGINE
SELECT * FROM `#mysql50##sql-ib-foo`;
DROP TABLE `#mysql50##sql-ib-foo`;

View File

@ -683,3 +683,15 @@ INSERT INTO t VALUES (NULL);
SELECT * FROM t;
SHOW CREATE TABLE t;
DROP TABLE t;
--echo #
--echo # MDEV-14008 Assertion failing: `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())
--echo #
SET sql_mode=STRICT_ALL_TABLES;
CREATE TABLE t1 (
c1 DOUBLE NOT NULL PRIMARY KEY AUTO_INCREMENT
) ENGINE=InnoDB AUTO_INCREMENT=10000000000000000000;
INSERT INTO t1 VALUES ();
SELECT * FROM t1;
DROP TABLE t1;

View File

@ -0,0 +1,10 @@
CREATE TABLE t1 (i INT) ENGINE=MYISAM
PARTITION BY LIST(i) (
PARTITION p0 VALUES IN (1),
PARTITION p1 VALUES IN (2)
);
ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
ALTER TABLE t1 DROP PARTITION p1;
SELECT * FROM t1;
i
DROP TABLE t1;

View File

@ -0,0 +1,17 @@
#
# MDEV-14641 Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine
#
--source include/have_partition.inc
CREATE TABLE t1 (i INT) ENGINE=MYISAM
PARTITION BY LIST(i) (
PARTITION p0 VALUES IN (1),
PARTITION p1 VALUES IN (2)
);
ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
ALTER TABLE t1 DROP PARTITION p1;
SELECT * FROM t1;
# Cleanup
DROP TABLE t1;

View File

@ -118,3 +118,19 @@ B
select count(*) from events_statements_history where sql_text like "%...";
count(*)
2
use test;
create table t1 (id int);
insert into t1 values (1), (2), (3);
truncate performance_schema.events_statements_history;
select * from t1;
id
1
2
3
insert into t1 select RAND()*10000 from t1;
select sql_text, rows_examined from performance_schema.events_statements_history;
sql_text rows_examined
truncate performance_schema.events_statements_history 0
select * from t1 3
insert into t1 select RAND()*10000 from t1 6
drop table t1;

View File

@ -207,3 +207,18 @@ select 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
select _utf8mb4 'васÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑвасÑ' as B;
select count(*) from events_statements_history where sql_text like "%...";
#
# MDEV-10486 MariaDB 10.x does not update rows_examined in performance_schema tables
# Verify that the rows_examined counter is set properly.
use test;
create table t1 (id int);
insert into t1 values (1), (2), (3);
truncate performance_schema.events_statements_history;
select * from t1;
insert into t1 select RAND()*10000 from t1;
select sql_text, rows_examined from performance_schema.events_statements_history;
drop table t1;

View File

@ -72,5 +72,25 @@ SELECT * FROM t2;
#Cleanup
DROP TABLE t1, t2;
# MDEV-14593 human-readable XA RECOVER
create table t1 (a int);
--write_file $MYSQLTEST_VARDIR/tmp/mdev-14593.sql
DELIMITER /
XA START 'tr1', 'bq'/
INSERT INTO t1 VALUES (0)/
XA END 'tr1', 'bq'/
XA PREPARE 'tr1', 'bq'/
XA RECOVER/
XA ROLLBACK 'tr1', 'bq'/
EOF
--exec $MYSQL test --binary-as-hex < $MYSQLTEST_VARDIR/tmp/mdev-14593.sql 2>&1
remove_file $MYSQLTEST_VARDIR/tmp/mdev-14593.sql;
#Cleanup
DROP TABLE t1;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc

View File

@ -1948,6 +1948,57 @@ cte2 as (
SELECT *
FROM cte1;
--echo #
--echo # mdev-14629: a user-defined variable is defined by the recursive CTE
--echo #
set @var=
(
with recursive cte_tab(a) as (
select 1
union
select a+1 from cte_tab
where a<3)
select count(*) from cte_tab
);
select @var;
create table t1(a int, b int);
insert into t1 values (3,8),(1,5),(5,7),(7,4),(4,3);
set @var=
(
with recursive summ(a,s) as (
select 1, 0 union
select t1.b, t1.b+summ.s from summ, t1
where summ.a=t1.a)
select s from summ
order by a desc
limit 1
);
select @var;
--ERROR ER_UNACCEPTABLE_MUTUAL_RECURSION
set @var=
(
with recursive
cte_1 as (
select 1
union
select * from cte_2),
cte_2 as (
select * from cte_1
union
select a from t1, cte_2
where t1.a=cte_2.a)
select * from cte_2
limit 1
);
drop table t1;
--echo #
--echo # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
--echo #
@ -1975,4 +2026,3 @@ DROP TABLE a_tbl;
--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT
WITH RECURSIVE x AS (SELECT 1,2 UNION ALL SELECT 1 FROM x) SELECT * FROM x;

View File

@ -80,9 +80,57 @@ xa rollback 'testa','testb';
xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
select * from t1;
disconnect con1;
--source include/wait_until_count_sessions.inc
connection default;
# MDEV-14593 human-readable XA RECOVER
xa start 'tr1';
insert t1 values (40);
xa end 'tr1';
xa prepare 'tr1';
xa recover format='SQL';
xa rollback 'tr1';
xa start 'tr1', 'bq';
insert t1 values (40);
xa end 'tr1', 'bq';
xa prepare 'tr1', 'bq';
xa recover format='SQL';
xa rollback 'tr1', 'bq';
xa start 'tr1', 'bq', 3;
insert t1 values (40);
xa end 'tr1', 'bq', 3;
xa prepare 'tr1', 'bq', 3;
xa recover format='SQL';
xa rollback 'tr1', 'bq', 3;
xa start 'tr1#$';
insert t1 values (40);
xa end 'tr1#$';
xa prepare 'tr1#$';
xa recover format='SQL';
xa rollback 'tr1#$';
xa start 'tr1#$', 'bq';
insert t1 values (40);
xa end 'tr1#$', 'bq';
xa prepare 'tr1#$', 'bq';
xa recover format='SQL';
xa rollback 'tr1#$', 'bq';
xa start 'tr1#$', 'bq', 3;
insert t1 values (40);
xa end 'tr1#$', 'bq', 3;
xa prepare 'tr1#$', 'bq', 3;
xa recover format='RAW';
--error ER_UNKNOWN_EXPLAIN_FORMAT
xa recover format='PLAIN';
xa recover format='SQL';
xa rollback 'tr1#$', 'bq', 3;
drop table t1;
#
@ -379,7 +427,6 @@ connection default;
DROP TABLE t1, t2;
disconnect con2;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc

View File

@ -37,6 +37,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c my_default.c
thr_rwlock.c thr_timer.c
tree.c typelib.c base64.c my_memmem.c
my_getpagesize.c
guess_malloc_library.c
lf_alloc-pin.c lf_dynarray.c lf_hash.c
safemalloc.c my_new.cc
my_getncpus.c my_safehash.c my_chmod.c my_rnd.c

View File

@ -0,0 +1,64 @@
/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
Copyright (c) 2012, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* guess_malloc_library() deduces, to the best of its ability,
the currently used malloc library and its version */
#include <stddef.h>
#include "my_global.h"
#include <m_string.h>
char *guess_malloc_library()
{
#ifndef HAVE_DLOPEN
return (char*) MALLOC_LIBRARY;
#else
static char buf[128];
if (strcmp(MALLOC_LIBRARY, "system") != 0)
{
return (char*) MALLOC_LIBRARY;
}
/* tcmalloc */
typedef const char* (*tc_version_type)(int*, int*, const char**);
tc_version_type tc_version_func =
(tc_version_type) dlsym(RTLD_DEFAULT, "tc_version");
if (tc_version_func)
{
int major, minor;
const char* ver_str = tc_version_func(&major, &minor, NULL);
strxnmov(buf, sizeof(buf)-1, "tcmalloc ", ver_str, NULL);
return buf;
}
/* jemalloc */
typedef int (*mallctl_type)(const char*, void*, size_t*, void*, size_t);
mallctl_type mallctl_func =
(mallctl_type) dlsym(RTLD_DEFAULT, "mallctl");
if (mallctl_func)
{
char *ver;
size_t len = sizeof(ver);
mallctl_func("version", &ver, &len, NULL, 0);
strxnmov(buf, sizeof(buf)-1, "jemalloc ", ver, NULL);
return buf;
}
return (char*) MALLOC_LIBRARY;
#endif
}

View File

@ -421,7 +421,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data)
DBUG_RETURN(ret);
#ifdef WITH_WSREP
error:
DBUG_RETURN(TRUE);
DBUG_RETURN(true);
#endif /* WITH_WSREP */
}

View File

@ -4677,6 +4677,15 @@ double Field_double::val_real(void)
}
longlong Field_double::val_int_from_real(bool want_unsigned_result)
{
Converter_double_to_longlong conv(val_real(), want_unsigned_result);
if (!want_unsigned_result && conv.error())
conv.push_warning(get_thd(), Field_double::val_real(), false);
return conv.result();
}
my_decimal *Field_real::val_decimal(my_decimal *decimal_value)
{
ASSERT_COLUMN_MARKED_FOR_READ;

View File

@ -842,6 +842,10 @@ public:
}
virtual double val_real(void)=0;
virtual longlong val_int(void)=0;
virtual ulonglong val_uint(void)
{
return (ulonglong) val_int();
}
virtual bool val_bool(void)= 0;
virtual my_decimal *val_decimal(my_decimal *);
inline String *val_str(String *str) { return val_str(str, str); }
@ -2195,6 +2199,7 @@ private:
class Field_double :public Field_real {
longlong val_int_from_real(bool want_unsigned_result);
public:
Field_double(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg,
@ -2232,13 +2237,8 @@ public:
int store(longlong nr, bool unsigned_val);
int reset(void) { bzero(ptr,sizeof(double)); return 0; }
double val_real(void);
longlong val_int(void)
{
Converter_double_to_longlong conv(Field_double::val_real(), false);
if (conv.error())
conv.push_warning(get_thd(), Field_double::val_real(), false);
return conv.result();
}
longlong val_int(void) { return val_int_from_real(false); }
ulonglong val_uint(void) { return (ulonglong) val_int_from_real(true); }
String *val_str(String*,String *);
bool send_binary(Protocol *protocol);
int cmp(const uchar *,const uchar *);

View File

@ -1992,6 +1992,97 @@ int ha_recover(HASH *commit_list)
DBUG_RETURN(0);
}
/**
return the XID as it appears in the SQL function's arguments.
So this string can be passed to XA START, XA PREPARE etc...
@note
the 'buf' has to have space for at least SQL_XIDSIZE bytes.
*/
/*
'a'..'z' 'A'..'Z', '0'..'9'
and '-' '_' ' ' symbols don't have to be
converted.
*/
static const char xid_needs_conv[128]=
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
};
uint get_sql_xid(XID *xid, char *buf)
{
int tot_len= xid->gtrid_length + xid->bqual_length;
int i;
const char *orig_buf= buf;
for (i=0; i<tot_len; i++)
{
uchar c= ((uchar *) xid->data)[i];
if (c >= 128 || xid_needs_conv[c])
break;
}
if (i >= tot_len)
{
/* No need to convert characters to hexadecimals. */
*buf++= '\'';
memcpy(buf, xid->data, xid->gtrid_length);
buf+= xid->gtrid_length;
*buf++= '\'';
if (xid->bqual_length > 0 || xid->formatID != 1)
{
*buf++= ',';
*buf++= '\'';
memcpy(buf, xid->data+xid->gtrid_length, xid->bqual_length);
buf+= xid->bqual_length;
*buf++= '\'';
}
}
else
{
*buf++= 'X';
*buf++= '\'';
for (i= 0; i < xid->gtrid_length; i++)
{
*buf++=_dig_vec_lower[((uchar*) xid->data)[i] >> 4];
*buf++=_dig_vec_lower[((uchar*) xid->data)[i] & 0x0f];
}
*buf++= '\'';
if (xid->bqual_length > 0 || xid->formatID != 1)
{
*buf++= ',';
*buf++= 'X';
*buf++= '\'';
for (; i < tot_len; i++)
{
*buf++=_dig_vec_lower[((uchar*) xid->data)[i] >> 4];
*buf++=_dig_vec_lower[((uchar*) xid->data)[i] & 0x0f];
}
*buf++= '\'';
}
}
if (xid->formatID != 1)
{
*buf++= ',';
buf+= my_longlong10_to_str_8bit(&my_charset_bin, buf,
MY_INT64_NUM_DECIMAL_DIGITS, -10, xid->formatID);
}
return buf - orig_buf;
}
/**
return the list of XID's to a client, the same way SHOW commands do.
@ -2001,7 +2092,8 @@ int ha_recover(HASH *commit_list)
It can be easily fixed later, if necessary.
*/
static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol)
static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol,
char *data, uint data_len, CHARSET_INFO *data_cs)
{
if (xs->xa_state == XA_PREPARED)
{
@ -2009,8 +2101,7 @@ static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol)
protocol->store_longlong((longlong) xs->xid.formatID, FALSE);
protocol->store_longlong((longlong) xs->xid.gtrid_length, FALSE);
protocol->store_longlong((longlong) xs->xid.bqual_length, FALSE);
protocol->store(xs->xid.data, xs->xid.gtrid_length + xs->xid.bqual_length,
&my_charset_bin);
protocol->store(data, data_len, data_cs);
if (protocol->write())
return TRUE;
}
@ -2018,11 +2109,28 @@ static my_bool xa_recover_callback(XID_STATE *xs, Protocol *protocol)
}
static my_bool xa_recover_callback_short(XID_STATE *xs, Protocol *protocol)
{
return xa_recover_callback(xs, protocol, xs->xid.data,
xs->xid.gtrid_length + xs->xid.bqual_length, &my_charset_bin);
}
static my_bool xa_recover_callback_verbose(XID_STATE *xs, Protocol *protocol)
{
char buf[SQL_XIDSIZE];
uint len= get_sql_xid(&xs->xid, buf);
return xa_recover_callback(xs, protocol, buf, len,
&my_charset_utf8_general_ci);
}
bool mysql_xa_recover(THD *thd)
{
List<Item> field_list;
Protocol *protocol= thd->protocol;
MEM_ROOT *mem_root= thd->mem_root;
my_hash_walk_action action;
DBUG_ENTER("mysql_xa_recover");
field_list.push_back(new (mem_root)
@ -2034,16 +2142,32 @@ bool mysql_xa_recover(THD *thd)
field_list.push_back(new (mem_root)
Item_int(thd, "bqual_length", 0,
MY_INT32_NUM_DECIMAL_DIGITS), mem_root);
{
uint len;
CHARSET_INFO *cs;
if (thd->lex->verbose)
{
len= SQL_XIDSIZE;
cs= &my_charset_utf8_general_ci;
action= (my_hash_walk_action) xa_recover_callback_verbose;
}
else
{
len= XIDDATASIZE;
cs= &my_charset_bin;
action= (my_hash_walk_action) xa_recover_callback_short;
}
field_list.push_back(new (mem_root)
Item_empty_string(thd, "data",
XIDDATASIZE), mem_root);
Item_empty_string(thd, "data", len, cs), mem_root);
}
if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(1);
if (xid_cache_iterate(thd, (my_hash_walk_action) xa_recover_callback,
protocol))
if (xid_cache_iterate(thd, action, protocol))
DBUG_RETURN(1);
my_eof(thd);
DBUG_RETURN(0);

View File

@ -669,6 +669,15 @@ struct xid_t {
};
typedef struct xid_t XID;
/*
The size of XID string representation in the form
'gtrid', 'bqual', formatID
see xid_t::get_sql_string() for details.
*/
#define SQL_XIDSIZE (XIDDATASIZE * 2 + 8 + MY_INT64_NUM_DECIMAL_DIGITS)
/* The 'buf' has to have space for at least SQL_XIDSIZE bytes. */
uint get_sql_xid(XID *xid, char *buf);
/* for recover() handlerton call */
#define MIN_XID_LIST_SIZE 128
#define MAX_XID_LIST_SIZE (1024*128)
@ -1824,6 +1833,13 @@ struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET);
return false;
}
ulong table_options_with_row_type()
{
if (row_type == ROW_TYPE_DYNAMIC || row_type == ROW_TYPE_PAGE)
return table_options | HA_OPTION_PACK_RECORD;
else
return table_options;
}
};

View File

@ -6850,8 +6850,8 @@ ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID
eng "GTID_NEXT cannot be changed by a client that owns a GTID. The client owns %s. Ownership is released on COMMIT or ROLLBACK"
ER_UNKNOWN_EXPLAIN_FORMAT
eng "Unknown EXPLAIN format name: '%s'"
rus "Неизвестное имя формата команды EXPLAIN: '%s'"
eng "Unknown %s format name: '%s'"
rus "Неизвестное имя формата команды %s: '%s'"
ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION 25006
eng "Cannot execute statement in a READ ONLY transaction"

View File

@ -2397,11 +2397,12 @@ com_multi_end:
THD_STAGE_INFO(thd, stage_cleaning_up);
thd->reset_query();
thd->set_examined_row_count(0); // For processlist
thd->set_command(COM_SLEEP);
/* Performance Schema Interface instrumentation, end */
MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
thd->set_examined_row_count(0); // For processlist
thd->set_command(COM_SLEEP);
thd->m_statement_psi= NULL;
thd->m_digest= NULL;
@ -5103,6 +5104,9 @@ end_with_restore_list:
{
List<set_var_base> *lex_var_list= &lex->var_list;
if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
goto error;
if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
|| open_and_lock_tables(thd, all_tables, TRUE, 0)))
goto error;

View File

@ -6560,10 +6560,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->part_info= part_info;
lpt->alter_info= alter_info;
lpt->create_info= create_info;
lpt->db_options= create_info->table_options;
if (create_info->row_type != ROW_TYPE_FIXED &&
create_info->row_type != ROW_TYPE_DEFAULT)
lpt->db_options|= HA_OPTION_PACK_RECORD;
lpt->db_options= create_info->table_options_with_row_type();
lpt->table= table;
lpt->key_info_buffer= 0;
lpt->key_count= 0;

View File

@ -4422,10 +4422,7 @@ handler *mysql_create_frm_image(THD *thd,
set_table_default_charset(thd, create_info, (char*) db);
db_options= create_info->table_options;
if (create_info->row_type == ROW_TYPE_DYNAMIC ||
create_info->row_type == ROW_TYPE_PAGE)
db_options|= HA_OPTION_PACK_RECORD;
db_options= create_info->table_options_with_row_type();
if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
create_info->db_type)))

View File

@ -430,14 +430,14 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
lex->link_first_table_back(view, link_to_local);
view->open_type= OT_BASE_ONLY;
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (check_dependencies_in_with_clauses(lex->with_clauses_list))
{
res= TRUE;
goto err;
}
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
/*
ignore lock specs for CREATE statement
*/

View File

@ -1692,7 +1692,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_default_time_precision
case_stmt_body opt_bin_mod
opt_if_exists_table_element opt_if_not_exists_table_element
opt_recursive
opt_recursive opt_format_xid
%type <object_ddl_options>
create_or_replace
@ -17134,9 +17134,26 @@ xa:
{
Lex->sql_command = SQLCOM_XA_ROLLBACK;
}
| XA_SYM RECOVER_SYM
| XA_SYM RECOVER_SYM opt_format_xid
{
Lex->sql_command = SQLCOM_XA_RECOVER;
Lex->verbose= $3;
}
;
opt_format_xid:
/* empty */ { $$= false; }
| FORMAT_SYM '=' ident_or_text
{
if (!my_strcasecmp(system_charset_info, $3.str, "SQL"))
$$= true;
else if (!my_strcasecmp(system_charset_info, $3.str, "RAW"))
$$= false;
else
{
my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), "XA RECOVER", $3.str));
$$= false;
}
}
;

View File

@ -35,6 +35,7 @@
#include "sql_priv.h"
#include "sql_class.h" // set_var.h: THD
#include "sys_vars.ic"
#include "my_sys.h"
#include "events.h"
#include <thr_alarm.h>
@ -3739,27 +3740,6 @@ static Sys_var_charptr Sys_version_source_revision(
CMD_LINE_HELP_ONLY,
IN_SYSTEM_CHARSET, DEFAULT(SOURCE_REVISION));
static char *guess_malloc_library()
{
if (strcmp(MALLOC_LIBRARY, "system") == 0)
{
#ifdef HAVE_DLOPEN
typedef int (*mallctl_type)(const char*, void*, size_t*, void*, size_t);
mallctl_type mallctl_func;
mallctl_func= (mallctl_type)dlsym(RTLD_DEFAULT, "mallctl");
if (mallctl_func)
{
static char buf[128];
char *ver;
size_t len = sizeof(ver);
mallctl_func("version", &ver, &len, NULL, 0);
strxnmov(buf, sizeof(buf)-1, "jemalloc ", ver, NULL);
return buf;
}
#endif
}
return const_cast<char*>(MALLOC_LIBRARY);
}
static char *malloc_library;
static Sys_var_charptr Sys_malloc_library(
"version_malloc_library", "Version of the used malloc library",

View File

@ -8386,7 +8386,7 @@ no_commit:
col_max_value = innobase_get_int_col_max_value(table->next_number_field);
/* Get the value that MySQL attempted to store in the table.*/
auto_inc = table->next_number_field->val_int();
auto_inc = table->next_number_field->val_uint();
switch (error) {
case DB_DUPLICATE_KEY:
@ -8852,12 +8852,7 @@ calc_row_difference(
if (field != table->found_next_number_field
|| dfield_is_null(&ufield->new_val)) {
} else {
auto_inc = row_parse_int(
static_cast<const byte*>(
ufield->new_val.data),
ufield->new_val.len,
col->mtype,
col->prtype & DATA_UNSIGNED);
auto_inc = field->val_uint();
}
}
n_changed++;

View File

@ -420,6 +420,10 @@ ulint
row_get_background_drop_list_len_low(void);
/*======================================*/
/** Drop garbage tables during recovery. */
void
row_mysql_drop_garbage_tables();
/*********************************************************************//**
Sets an exclusive lock on a table.
@return error code or DB_SUCCESS */

View File

@ -3462,6 +3462,8 @@ recv_recovery_rollback_active(void)
/* Drop partially created indexes. */
row_merge_drop_temp_indexes();
/* Drop garbage tables. */
row_mysql_drop_garbage_tables();
/* Drop any auxiliary tables that were not dropped when the
parent table was dropped. This can happen if the parent table

View File

@ -64,6 +64,7 @@ Created 9/17/2000 Heikki Tuuri
#include "trx0roll.h"
#include "trx0undo.h"
#include "row0ext.h"
#include "srv0start.h"
#include "ut0new.h"
#include <algorithm>
@ -75,7 +76,7 @@ ibool row_rollback_on_timeout = FALSE;
/** Chain node of the list of tables to drop in the background. */
struct row_mysql_drop_t{
char* table_name; /*!< table name */
table_id_t table_id; /*!< table id */
UT_LIST_NODE_T(row_mysql_drop_t)row_mysql_drop_list;
/*!< list chain node */
};
@ -112,19 +113,6 @@ row_mysql_is_system_table(
|| 0 == strcmp(name + 6, "db"));
}
/*********************************************************************//**
If a table is not yet in the drop list, adds the table to the list of tables
which the master thread drops in background. We need this on Unix because in
ALTER TABLE MySQL may call drop table even if the table has running queries on
it. Also, if there are running foreign key checks on the table, we drop the
table lazily.
@return TRUE if the table was not yet in the drop list, and was added there */
static
ibool
row_add_table_to_background_drop_list(
/*==================================*/
const char* name); /*!< in: table name */
#ifdef UNIV_DEBUG
/** Wait for the background drop list to become empty. */
void
@ -2791,12 +2779,6 @@ row_drop_table_for_mysql_in_background(
error = row_drop_table_for_mysql(name, trx, FALSE, FALSE);
/* Flush the log to reduce probability that the .frm files and
the InnoDB data dictionary get out-of-sync if the user runs
with innodb_flush_log_at_trx_commit = 0 */
log_buffer_flush_to_disk();
trx_commit_for_mysql(trx);
trx_free_for_background(trx);
@ -2821,7 +2803,7 @@ loop:
mutex_enter(&row_drop_list_mutex);
ut_a(row_mysql_drop_list_inited);
next:
drop = UT_LIST_GET_FIRST(row_mysql_drop_list);
n_tables = UT_LIST_GET_LEN(row_mysql_drop_list);
@ -2834,61 +2816,41 @@ loop:
return(n_tables + n_tables_dropped);
}
DBUG_EXECUTE_IF("row_drop_tables_in_background_sleep",
os_thread_sleep(5000000);
);
/* On fast shutdown, just empty the list without dropping tables. */
table = srv_shutdown_state == SRV_SHUTDOWN_NONE || !srv_fast_shutdown
? dict_table_open_on_id(drop->table_id, FALSE,
DICT_TABLE_OP_OPEN_ONLY_IF_CACHED)
: NULL;
table = dict_table_open_on_name(drop->table_name, FALSE, FALSE,
DICT_ERR_IGNORE_NONE);
if (table == NULL) {
/* If for some reason the table has already been dropped
through some other mechanism, do not try to drop it */
goto already_dropped;
}
if (!table->to_be_dropped) {
/* There is a scenario: the old table is dropped
just after it's added into drop list, and new
table with the same name is created, then we try
to drop the new table in background. */
dict_table_close(table, FALSE, FALSE);
goto already_dropped;
if (!table) {
n_tables_dropped++;
mutex_enter(&row_drop_list_mutex);
UT_LIST_REMOVE(row_mysql_drop_list, drop);
MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE);
ut_free(drop);
goto next;
}
ut_a(!table->can_be_evicted);
if (!table->to_be_dropped) {
dict_table_close(table, FALSE, FALSE);
mutex_enter(&row_drop_list_mutex);
UT_LIST_REMOVE(row_mysql_drop_list, drop);
UT_LIST_ADD_LAST(row_mysql_drop_list, drop);
goto next;
}
dict_table_close(table, FALSE, FALSE);
if (DB_SUCCESS != row_drop_table_for_mysql_in_background(
drop->table_name)) {
table->name.m_name)) {
/* If the DROP fails for some table, we return, and let the
main thread retry later */
return(n_tables + n_tables_dropped);
}
n_tables_dropped++;
already_dropped:
mutex_enter(&row_drop_list_mutex);
UT_LIST_REMOVE(row_mysql_drop_list, drop);
MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE);
ib::info() << "Dropped table "
<< ut_get_name(NULL, drop->table_name)
<< " in background drop queue.",
ut_free(drop->table_name);
ut_free(drop);
mutex_exit(&row_drop_list_mutex);
goto loop;
}
@ -2913,20 +2875,87 @@ row_get_background_drop_list_len_low(void)
return(len);
}
/** Drop garbage tables during recovery. */
void
row_mysql_drop_garbage_tables()
{
mem_heap_t* heap = mem_heap_create(FN_REFLEN);
btr_pcur_t pcur;
mtr_t mtr;
trx_t* trx = trx_allocate_for_background();
trx->op_info = "dropping garbage tables";
row_mysql_lock_data_dictionary(trx);
mtr.start();
btr_pcur_open_at_index_side(
true, dict_table_get_first_index(dict_sys->sys_tables),
BTR_SEARCH_LEAF, &pcur, true, 0, &mtr);
for (;;) {
const rec_t* rec;
const byte* field;
ulint len;
const char* table_name;
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
if (!btr_pcur_is_on_user_rec(&pcur)) {
break;
}
rec = btr_pcur_get_rec(&pcur);
if (rec_get_deleted_flag(rec, 0)) {
continue;
}
field = rec_get_nth_field_old(rec, 0/*NAME*/, &len);
if (len == UNIV_SQL_NULL || len == 0) {
/* Corrupted SYS_TABLES.NAME */
continue;
}
table_name = mem_heap_strdupl(
heap,
reinterpret_cast<const char*>(field), len);
if (strstr(table_name, "/" TEMP_FILE_PREFIX_INNODB)) {
btr_pcur_store_position(&pcur, &mtr);
btr_pcur_commit_specify_mtr(&pcur, &mtr);
if (dict_load_table(table_name, true,
DICT_ERR_IGNORE_ALL)) {
row_drop_table_for_mysql(
table_name, trx, FALSE, FALSE);
trx_commit_for_mysql(trx);
}
mtr.start();
btr_pcur_restore_position(BTR_SEARCH_LEAF,
&pcur, &mtr);
}
mem_heap_empty(heap);
}
btr_pcur_close(&pcur);
mtr.commit();
row_mysql_unlock_data_dictionary(trx);
trx_free_for_background(trx);
mem_heap_free(heap);
}
/*********************************************************************//**
If a table is not yet in the drop list, adds the table to the list of tables
which the master thread drops in background. We need this on Unix because in
ALTER TABLE MySQL may call drop table even if the table has running queries on
it. Also, if there are running foreign key checks on the table, we drop the
table lazily.
@return TRUE if the table was not yet in the drop list, and was added there */
@return whether background DROP TABLE was scheduled for the first time */
static
ibool
row_add_table_to_background_drop_list(
/*==================================*/
const char* name) /*!< in: table name */
bool
row_add_table_to_background_drop_list(table_id_t table_id)
{
row_mysql_drop_t* drop;
bool added = true;
mutex_enter(&row_drop_list_mutex);
@ -2937,27 +2966,21 @@ row_add_table_to_background_drop_list(
drop != NULL;
drop = UT_LIST_GET_NEXT(row_mysql_drop_list, drop)) {
if (strcmp(drop->table_name, name) == 0) {
/* Already in the list */
mutex_exit(&row_drop_list_mutex);
return(FALSE);
if (drop->table_id == table_id) {
added = false;
goto func_exit;
}
}
drop = static_cast<row_mysql_drop_t*>(
ut_malloc_nokey(sizeof(row_mysql_drop_t)));
drop->table_name = mem_strdup(name);
drop = static_cast<row_mysql_drop_t*>(ut_malloc_nokey(sizeof *drop));
drop->table_id = table_id;
UT_LIST_ADD_LAST(row_mysql_drop_list, drop);
MONITOR_INC(MONITOR_BACKGROUND_DROP_TABLE);
func_exit:
mutex_exit(&row_drop_list_mutex);
return(TRUE);
return added;
}
/** Reassigns the table identifier of a table.
@ -3690,11 +3713,7 @@ row_drop_table_for_mysql(
}
DBUG_EXECUTE_IF("row_drop_table_add_to_background",
row_add_table_to_background_drop_list(table->name.m_name);
err = DB_SUCCESS;
goto funct_exit;
);
DBUG_EXECUTE_IF("row_drop_table_add_to_background", goto defer;);
/* TODO: could we replace the counter n_foreign_key_checks_running
with lock checks on the table? Acquire here an exclusive lock on the
@ -3703,28 +3722,22 @@ row_drop_table_for_mysql(
checks take an IS or IX lock on the table. */
if (table->n_foreign_key_checks_running > 0) {
const char* save_tablename = table->name.m_name;
ibool added;
added = row_add_table_to_background_drop_list(save_tablename);
if (added) {
ib::info() << "You are trying to drop table "
<< table->name
<< " though there is a foreign key check"
" running on it. Adding the table to the"
" background drop queue.";
/* We return DB_SUCCESS to MySQL though the drop will
happen lazily later */
err = DB_SUCCESS;
defer:
if (!strstr(table->name.m_name, "/" TEMP_FILE_PREFIX_INNODB)) {
heap = mem_heap_create(FN_REFLEN);
const char* tmp_name
= dict_mem_create_temporary_tablename(
heap, table->name.m_name, table->id);
ib::info() << "Deferring DROP TABLE " << table->name
<< "; renaming to " << tmp_name;
err = row_rename_table_for_mysql(
table->name.m_name, tmp_name, trx, false);
} else {
/* The table is already in the background drop list */
err = DB_ERROR;
err = DB_SUCCESS;
}
if (err == DB_SUCCESS) {
row_add_table_to_background_drop_list(table->id);
}
goto funct_exit;
}
@ -3745,31 +3758,9 @@ row_drop_table_for_mysql(
/* Wait on background threads to stop using table */
fil_wait_crypt_bg_threads(table);
if (table->get_ref_count() == 0) {
lock_remove_all_on_table(table, TRUE);
ut_a(table->n_rec_locks == 0);
} else if (table->get_ref_count() > 0 || table->n_rec_locks > 0) {
ibool added;
added = row_add_table_to_background_drop_list(
table->name.m_name);
if (added) {
ib::info() << "MySQL is trying to drop table "
<< table->name
<< " though there are still open handles to"
" it. Adding the table to the background drop"
" queue.";
/* We return DB_SUCCESS to MySQL though the drop will
happen lazily later */
err = DB_SUCCESS;
} else {
/* The table is already in the background drop list */
err = DB_ERROR;
}
goto funct_exit;
if (table->get_ref_count() > 0 || table->n_rec_locks > 0
|| lock_table_has_locks(table)) {
goto defer;
}
/* The "to_be_dropped" marks table that is to be dropped, but
@ -3779,11 +3770,6 @@ row_drop_table_for_mysql(
and it is free to be dropped */
table->to_be_dropped = false;
/* If we get this far then the table to be dropped must not have
any table or record locks on it. */
ut_a(!lock_table_has_locks(table));
switch (trx_get_dict_operation(trx)) {
case TRX_DICT_OP_NONE:
trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);

View File

@ -5958,8 +5958,10 @@ rdb_is_index_collation_supported(const my_core::Field *const field) {
/* Handle [VAR](CHAR|BINARY) or TEXT|BLOB */
if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_STRING ||
type == MYSQL_TYPE_BLOB) {
return RDB_INDEX_COLLATIONS.find(field->charset()->number) !=
RDB_INDEX_COLLATIONS.end();
return (RDB_INDEX_COLLATIONS.find(field->charset()->number) !=
RDB_INDEX_COLLATIONS.end()) ||
rdb_is_collation_supported(field->charset());
}
return true;
}
@ -6118,18 +6120,16 @@ int ha_rocksdb::create_cfs(
!rdb_is_index_collation_supported(
table_arg->key_info[i].key_part[part].field) &&
!rdb_collation_exceptions->matches(tablename_sys)) {
std::string collation_err;
for (const auto &coll : RDB_INDEX_COLLATIONS) {
if (collation_err != "") {
collation_err += ", ";
}
collation_err += get_charset_name(coll);
}
my_error(ER_UNSUPPORTED_COLLATION, MYF(0),
char buf[1024];
my_snprintf(buf, sizeof(buf),
"Indexed column %s.%s uses a collation that does not "
"allow index-only access in secondary key and has "
"reduced disk space efficiency in primary key.",
tbl_def_arg->full_tablename().c_str(),
table_arg->key_info[i].key_part[part].field->field_name.str,
collation_err.c_str());
DBUG_RETURN(HA_EXIT_FAILURE);
table_arg->key_info[i].key_part[part].field->field_name.str);
my_error(ER_INTERNAL_ERROR, MYF(ME_JUST_WARNING), buf);
}
}
}
@ -12338,6 +12338,7 @@ void rocksdb_set_update_cf_options(THD *const /* unused */,
// Basic sanity checking and parsing the options into a map. If this fails
// then there's no point to proceed.
if (!Rdb_cf_options::parse_cf_options(val, &option_map)) {
my_free(*reinterpret_cast<char**>(var_ptr));
*reinterpret_cast<char**>(var_ptr) = nullptr;
// NO_LINT_DEBUG
@ -12406,6 +12407,7 @@ void rocksdb_set_update_cf_options(THD *const /* unused */,
// the CF options. This will results in consistent behavior and avoids
// dealing with cases when only a subset of CF-s was successfully updated.
if (val) {
my_free(*reinterpret_cast<char**>(var_ptr));
*reinterpret_cast<char**>(var_ptr) = my_strdup(val, MYF(0));
} else {
*reinterpret_cast<char**>(var_ptr) = nullptr;
@ -12500,6 +12502,7 @@ void print_keydup_error(TABLE *table, KEY *key, myf errflag,
its name generation.
*/
struct st_mysql_storage_engine rocksdb_storage_engine = {
MYSQL_HANDLERTON_INTERFACE_VERSION};
@ -12516,7 +12519,7 @@ maria_declare_plugin(rocksdb_se){
myrocks::rocksdb_status_vars, /* status variables */
myrocks::rocksdb_system_variables, /* system variables */
"1.0", /* string version */
MariaDB_PLUGIN_MATURITY_ALPHA /* maturity */
myrocks::MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
},
myrocks::rdb_i_s_cfstats, myrocks::rdb_i_s_dbstats,
myrocks::rdb_i_s_perf_context, myrocks::rdb_i_s_perf_context_global,

View File

@ -1411,4 +1411,7 @@ private:
Rdb_inplace_alter_ctx(const Rdb_inplace_alter_ctx &);
Rdb_inplace_alter_ctx &operator=(const Rdb_inplace_alter_ctx &);
};
const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_ALPHA;
} // namespace myrocks

View File

@ -279,8 +279,15 @@ DROP TABLE t1;
set @tmp_rocksdb_strict_collation_check= @@rocksdb_strict_collation_check;
set global rocksdb_strict_collation_check=1;
CREATE TABLE t1 (a INT, b TEXT);
# MariaDB no longer gives ER_UNSUPPORTED_COLLATION
ALTER TABLE t1 ADD KEY kb(b(10));
ERROR HY000: Unsupported collation on string indexed column test.t1.b Use binary collation (latin1_bin, binary, utf8_bin).
ALTER TABLE t1 ADD PRIMARY KEY(a);
DROP TABLE t1;
CREATE TABLE t1 (a INT, b TEXT collate utf8_general_ci);
# MariaDB no longer gives ER_UNSUPPORTED_COLLATION
ALTER TABLE t1 ADD KEY kb(b(10));
Warnings:
Warning 1815 Internal error: Indexed column test.t1.b uses a collation that does not allow index-only access in secondary key and has reduced disk space efficiency in primary key.
ALTER TABLE t1 ADD PRIMARY KEY(a);
DROP TABLE t1;
set global rocksdb_strict_collation_check= @tmp_rocksdb_strict_collation_check;

View File

@ -64,3 +64,20 @@ set global rocksdb_strict_collation_check=off;
create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb;
ERROR HY000: MyRocks doesn't currently support collations with "No pad" attribute.
set global rocksdb_strict_collation_check=@tmp_rscc;
#
# MDEV-14679: RocksdB plugin fails to load with "Loading of unknown plugin ROCKSDB_CFSTATS
#
select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%';
plugin_name plugin_maturity
ROCKSDB Alpha
ROCKSDB_CFSTATS Alpha
ROCKSDB_DBSTATS Alpha
ROCKSDB_PERF_CONTEXT Alpha
ROCKSDB_PERF_CONTEXT_GLOBAL Alpha
ROCKSDB_CF_OPTIONS Alpha
ROCKSDB_COMPACTION_STATS Alpha
ROCKSDB_GLOBAL_INFO Alpha
ROCKSDB_DDL Alpha
ROCKSDB_INDEX_FILE_MAP Alpha
ROCKSDB_LOCKS Alpha
ROCKSDB_TRX Alpha

View File

@ -173,10 +173,17 @@ set @tmp_rocksdb_strict_collation_check= @@rocksdb_strict_collation_check;
set global rocksdb_strict_collation_check=1;
CREATE TABLE t1 (a INT, b TEXT);
--error ER_UNSUPPORTED_COLLATION
--echo # MariaDB no longer gives ER_UNSUPPORTED_COLLATION
ALTER TABLE t1 ADD KEY kb(b(10));
ALTER TABLE t1 ADD PRIMARY KEY(a);
DROP TABLE t1;
CREATE TABLE t1 (a INT, b TEXT collate utf8_general_ci);
--echo # MariaDB no longer gives ER_UNSUPPORTED_COLLATION
ALTER TABLE t1 ADD KEY kb(b(10));
ALTER TABLE t1 ADD PRIMARY KEY(a);
DROP TABLE t1;
set global rocksdb_strict_collation_check= @tmp_rocksdb_strict_collation_check;
# make sure race condition between connection close and alter on another

View File

@ -67,3 +67,9 @@ set global rocksdb_strict_collation_check=off;
create table t1 (pk varchar(10) collate latin1_nopad_bin, primary key(pk)) engine=rocksdb;
set global rocksdb_strict_collation_check=@tmp_rscc;
--echo #
--echo # MDEV-14679: RocksdB plugin fails to load with "Loading of unknown plugin ROCKSDB_CFSTATS
--echo #
select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%';

View File

@ -2921,7 +2921,7 @@ std::array<const Rdb_collation_codec *, MY_ALL_CHARSETS_SIZE>
rdb_collation_data;
mysql_mutex_t rdb_collation_data_mutex;
static bool rdb_is_collation_supported(const my_core::CHARSET_INFO *const cs) {
bool rdb_is_collation_supported(const my_core::CHARSET_INFO *const cs) {
return cs->strxfrm_multiply==1 && cs->mbmaxlen == 1 &&
!(cs->state & (MY_CS_BINSORT | MY_CS_NOPAD));
}

View File

@ -1362,4 +1362,6 @@ struct Rdb_index_info {
uint64 m_ttl_duration = 0;
};
bool rdb_is_collation_supported(const my_core::CHARSET_INFO *const cs);
} // namespace myrocks

View File

@ -1484,7 +1484,7 @@ struct st_maria_plugin rdb_i_s_cfstats = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_dbstats = {
@ -1500,7 +1500,7 @@ struct st_maria_plugin rdb_i_s_dbstats = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_perf_context = {
@ -1516,7 +1516,7 @@ struct st_maria_plugin rdb_i_s_perf_context = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_perf_context_global = {
@ -1532,7 +1532,7 @@ struct st_maria_plugin rdb_i_s_perf_context_global = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_cfoptions = {
@ -1548,7 +1548,7 @@ struct st_maria_plugin rdb_i_s_cfoptions = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_global_info = {
@ -1564,7 +1564,7 @@ struct st_maria_plugin rdb_i_s_global_info = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_compact_stats = {
@ -1580,7 +1580,7 @@ struct st_maria_plugin rdb_i_s_compact_stats = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_ddl = {
@ -1596,7 +1596,7 @@ struct st_maria_plugin rdb_i_s_ddl = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_index_file_map = {
@ -1612,7 +1612,7 @@ struct st_maria_plugin rdb_i_s_index_file_map = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_lock_info = {
@ -1628,7 +1628,7 @@ struct st_maria_plugin rdb_i_s_lock_info = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
struct st_maria_plugin rdb_i_s_trx_info = {
@ -1644,6 +1644,6 @@ struct st_maria_plugin rdb_i_s_trx_info = {
nullptr, /* status variables */
nullptr, /* system variables */
nullptr, /* config options */
0, /* flags */
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
} // namespace myrocks

View File

@ -4,13 +4,17 @@ IF(CMAKE_VERSION VERSION_LESS "2.8.9")
MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")
ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR
CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")
# tokudb requires F_NOCACHE, O_DIRECT, and designated initializers
# tokudb requires F_NOCACHE or O_DIRECT, and designated initializers
CHECK_CXX_SOURCE_COMPILES(
"
#include <fcntl.h>
struct a {int b; int c; };
struct a d = { .b=1, .c=2 };
int main() { return F_NOCACHE + O_DIRECT; }
#if defined(O_DIRECT) || defined(F_NOCACHE)
int main() { return 0; }
#else
#error
#endif
" TOKUDB_OK)
ENDIF()

View File

@ -13,7 +13,9 @@
# and probably others
[Unit]
Description=MariaDB database server
Description=MariaDB @VERSION@ database server
Documentation=man:mysqld(8)
Documentation=https://mariadb.com/kb/en/library/systemd/
After=network.target
After=syslog.target
@ -76,7 +78,7 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \
# Start main service
# MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf
# Use the [service] section and Environment="MYSQLD_OPTS=...".
# Use the [Service] section and Environment="MYSQLD_OPTS=...".
# This isn't a replacement for my.cnf.
# _WSREP_NEW_CLUSTER is for the exclusive use of the script galera_new_cluster
ExecStart=@sbindir@/mysqld $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION
@ -103,7 +105,8 @@ UMask=007
##
##
## by creating a file in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf
## and adding/setting the following will override this file's settings.
## and adding/setting the following under [Service] will override this file's
## settings.
# Useful options not previously available in [mysqld_safe]

View File

@ -18,7 +18,9 @@
# Inspired from https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-db/mysql-init-scripts/files/mysqld_at.service
[Unit]
Description=MariaDB database server
Description=MariaDB @VERSION@ database server (multi-instance)
Documentation=man:mysqld(8)
Documentation=https://mariadb.com/kb/en/library/systemd/
After=network.target
After=syslog.target
@ -89,7 +91,7 @@ ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \
# Start main service
# MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb@.service.d/MY_SPECIAL.conf
# Use the [service] section and Environment="MYSQLD_OPTS=...".
# Use the [Service] section and Environment="MYSQLD_OPTS=...".
# This isn't a replacement for my.cnf.
# _WSREP_NEW_CLUSTER is for the exclusive use of the script galera_new_cluster
@ -124,7 +126,8 @@ UMask=007
##
##
## by creating a file in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf
## and adding/setting the following will override this file's settings.
## and adding/setting the following below [Service] will override this file's
## settings.
# Useful options not previously available in [mysqld_safe]