1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

Merge bb-10.2-ext into 10.3

This commit is contained in:
Marko Mäkelä
2017-12-14 11:34:30 +02:00
58 changed files with 663 additions and 378 deletions

View File

@@ -166,8 +166,8 @@ static struct my_option my_long_options[]=
"server with which it was built/distributed.",
&opt_version_check, &opt_version_check, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"write-binlog", OPT_WRITE_BINLOG, "All commands including those, "
"issued by mysqlcheck, are written to the binary log.",
{"write-binlog", OPT_WRITE_BINLOG, "All commands including those "
"issued by mysqlcheck are written to the binary log.",
&opt_write_binlog, &opt_write_binlog, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}

View File

@@ -63,6 +63,12 @@ typedef struct st_mysql_lex_string LEX_STRING;
/* NO and OK is the same used just to show semantics */
#define ER_DYNCOL_NO ER_DYNCOL_OK
#ifdef HAVE_CHARSET_utf8mb4
#define DYNCOL_UTF (&my_charset_utf8mb4_general_ci)
#else
#define DYNCOL_UTF (&my_charset_utf8_general_ci)
#endif
enum enum_dyncol_func_result
{
ER_DYNCOL_OK= 0,

View File

@@ -691,8 +691,7 @@ it was built/distributed. Defaults to on; use \fB\-\-skip\-version\-check\fR to
.sp
Cause binary logging to be enabled while
\fBmysql_upgrade\fR
runs\&. This is the default behavior; to disable binary logging during the upgrade, use the inverse of this option (that is, start the program with
\fB\-\-skip\-write\-binlog\fR)\&.
runs\&.
.RE
.SH "COPYRIGHT"
.br

View File

@@ -1,15 +0,0 @@
if (!$restart_parameters)
{
let $restart_parameters = restart;
}
--let $_server_id= `SELECT @@server_id`
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
--echo # Kill and $restart_parameters
--exec echo "$restart_parameters" > $_expect_file_name
--shutdown_server 0
--source include/wait_until_disconnected.inc
--enable_reconnect
--source include/wait_until_connected_again.inc
--disable_reconnect

View File

@@ -10272,6 +10272,21 @@ DROP TABLE allbytes;
SET sql_mode = DEFAULT;
# End of ctype_backslash.inc
#
# MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
#
SET NAMES utf8;
SELECT CHAR(0xDF USING latin1);
CHAR(0xDF USING latin1)
ß
CREATE OR REPLACE VIEW v1 AS SELECT CHAR(0xDF USING latin1) AS c;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select char(0xdf using latin1) AS `c` utf8 utf8_general_ci
SELECT * FROM v1;
c
ß
DROP VIEW v1;
#
# End of 10.0 tests
#
#

View File

@@ -3430,6 +3430,32 @@ a b
a 😁 b a ? b
DROP TABLE t1;
#
# MDEV-8949: COLUMN_CREATE unicode name breakage
#
SET NAMES utf8mb4;
SELECT COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1))
{"😎":1}
SELECT COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1))
`😎`
SELECT COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E
as int);
COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E
as int)
1
CREATE TABLE t1 AS SELECT
COLUMN_LIST(COLUMN_CREATE('a',1)),
COLUMN_JSON(COLUMN_CREATE('b',1));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`COLUMN_LIST(COLUMN_CREATE('a',1))` longtext CHARACTER SET utf8mb4 DEFAULT NULL,
`COLUMN_JSON(COLUMN_CREATE('b',1))` longtext CHARACTER SET utf8mb4 DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
SET NAMES default;
#
# End of 10.0 tests
#
#

View File

@@ -4734,6 +4734,27 @@ set global max_allowed_packet=default;
# End of 5.6 tests
#
#
# Start of 10.0 tests
#
#
# MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
#
EXPLAIN EXTENDED SELECT CHAR(0xDF USING latin1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select char(0xdf using latin1) AS `CHAR(0xDF USING latin1)`
EXPLAIN EXTENDED SELECT CHAR(0xDF USING `binary`);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select char(0xdf) AS `CHAR(0xDF USING ``binary``)`
EXPLAIN EXTENDED SELECT CHAR(0xDF);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select char(0xdf) AS `CHAR(0xDF)`
#
# Start of 10.1 tests
#
#
@@ -4843,6 +4864,12 @@ YQ== 61
Yq== 62
DROP TABLE t1;
#
# End of 10.1 tests
#
#
# Start of 10.3 tests
#
#
# MDEV-12685 Oracle-compatible function CHR()
#
select chr(65);
@@ -4859,12 +4886,6 @@ utf8 3 1
drop database mysqltest1;
use test;
#
# End of 10.1 tests
#
#
# Start of 10.3 tests
#
#
# MDEV-12592 Illegal mix of collations with the HEX function
#
SET NAMES utf8;

View File

@@ -134,3 +134,23 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
ERROR HY000: Column 'c2' is not updatable
DROP VIEW v1;
DROP TABLE t1;
#
# MDEV-14628 Wrong autoinc value assigned by LOAD XML in the NO_AUTO_VALUE_ON_ZERO mode
#
SET sql_mode=NO_AUTO_VALUE_ON_ZERO;
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT);
LOAD XML INFILE '../../std_data/loaddata/mdev14628a.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
SELECT * FROM t1 ORDER BY b;
a b
1 bbb1
2 bbb2
DROP TABLE t1;
SET sql_mode=DEFAULT;
SET sql_mode='';
CREATE TABLE t1 (id INT, g GEOMETRY NOT NULL);
LOAD XML INFILE '../../std_data/loaddata/mdev14628b.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
ERROR 22004: Column set to default value; NULL supplied to NOT NULL column 'g' at row 1
SELECT * FROM t1;
id g
DROP TABLE t1;
SET sql_mode=DEFAULT;

View File

@@ -0,0 +1,4 @@
<list>
<row a="1" b="bbb1"/>
<row b="bbb2"/>
</list>

View File

@@ -0,0 +1,3 @@
<list>
<row id="1"/>
</list>

View File

@@ -0,0 +1,64 @@
#
# MDEV-13797 InnoDB may hang if shutdown is initiated soon after startup
# while rolling back recovered incomplete transactions
#
CREATE TABLE t (a INT) ENGINE=InnoDB;
BEGIN;
COMMIT;
connect con$c,localhost,root,,;
CREATE TABLE t8 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
BEGIN;
INSERT INTO t8 (a) SELECT NULL FROM t;
UPDATE t8 SET a=a+100, b=a;
DELETE FROM t8;
connect con$c,localhost,root,,;
CREATE TABLE t7 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
BEGIN;
INSERT INTO t7 (a) SELECT NULL FROM t;
UPDATE t7 SET a=a+100, b=a;
DELETE FROM t7;
connect con$c,localhost,root,,;
CREATE TABLE t6 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
BEGIN;
INSERT INTO t6 (a) SELECT NULL FROM t;
UPDATE t6 SET a=a+100, b=a;
DELETE FROM t6;
connect con$c,localhost,root,,;
CREATE TABLE t5 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
BEGIN;
INSERT INTO t5 (a) SELECT NULL FROM t;
UPDATE t5 SET a=a+100, b=a;
DELETE FROM t5;
connect con$c,localhost,root,,;
CREATE TABLE t4 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
BEGIN;
INSERT INTO t4 (a) SELECT NULL FROM t;
UPDATE t4 SET a=a+100, b=a;
DELETE FROM t4;
connect con$c,localhost,root,,;
CREATE TABLE t3 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
BEGIN;
INSERT INTO t3 (a) SELECT NULL FROM t;
UPDATE t3 SET a=a+100, b=a;
DELETE FROM t3;
connect con$c,localhost,root,,;
CREATE TABLE t2 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
BEGIN;
INSERT INTO t2 (a) SELECT NULL FROM t;
UPDATE t2 SET a=a+100, b=a;
DELETE FROM t2;
connect con$c,localhost,root,,;
CREATE TABLE t1 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
BEGIN;
INSERT INTO t1 (a) SELECT NULL FROM t;
UPDATE t1 SET a=a+100, b=a;
DELETE FROM t1;
INSERT INTO t1(a) SELECT NULL FROM t;
INSERT INTO t1(a) SELECT NULL FROM t1;
INSERT INTO t1(a) SELECT NULL FROM t1;
INSERT INTO t1(a) SELECT NULL FROM t1;
INSERT INTO t1(a) SELECT NULL FROM t1;
connection default;
SET GLOBAL innodb_flush_log_at_trx_commit=1;
CREATE TABLE u(a SERIAL) ENGINE=INNODB;
DROP TABLE t,u;

View File

@@ -43,7 +43,6 @@ XA PREPARE 'xatrx';
CONNECT con1,localhost,root,,;
call mtr.add_suppression("Found 1 prepared XA transactions");
FLUSH TABLES;
# Kill and restart
SELECT update_time FROM information_schema.tables WHERE table_name = 't';
update_time
NULL

View File

@@ -0,0 +1,59 @@
--source include/have_innodb.inc
--source include/not_embedded.inc
--echo #
--echo # MDEV-13797 InnoDB may hang if shutdown is initiated soon after startup
--echo # while rolling back recovered incomplete transactions
--echo #
CREATE TABLE t (a INT) ENGINE=InnoDB;
let $size = 100;
let $trx = 8;
let $c = $size;
BEGIN;
--disable_query_log
while ($c) {
INSERT INTO t VALUES();
dec $c;
}
--enable_query_log
COMMIT;
let $c = $trx;
while ($c)
{
connect (con$c,localhost,root,,);
eval CREATE TABLE t$c (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
BEGIN;
eval INSERT INTO t$c (a) SELECT NULL FROM t;
eval UPDATE t$c SET a=a+$size, b=a;
eval DELETE FROM t$c;
dec $c;
}
INSERT INTO t1(a) SELECT NULL FROM t;
INSERT INTO t1(a) SELECT NULL FROM t1;
INSERT INTO t1(a) SELECT NULL FROM t1;
INSERT INTO t1(a) SELECT NULL FROM t1;
INSERT INTO t1(a) SELECT NULL FROM t1;
--connection default
SET GLOBAL innodb_flush_log_at_trx_commit=1;
CREATE TABLE u(a SERIAL) ENGINE=INNODB;
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
--let $shutdown_timeout=60
--source include/restart_mysqld.inc
--disable_query_log
let $c = $trx;
while ($c)
{
disconnect con$c;
eval DROP TABLE t$c;
dec $c;
}
--enable_query_log
DROP TABLE t,u;

View File

@@ -1 +1 @@
--innodb-open-files=13
--innodb-open-files=20

View File

@@ -67,7 +67,8 @@ CONNECT (con1,localhost,root,,);
call mtr.add_suppression("Found 1 prepared XA transactions");
FLUSH TABLES;
--source include/kill_and_restart_mysqld.inc
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
SELECT update_time FROM information_schema.tables WHERE table_name = 't';

View File

@@ -36,6 +36,5 @@ call mtr.add_suppression("InnoDB: A copy of page \[page id: space=[0-9]+, page n
START TRANSACTION;
CALL insert_t1(5000);
COMMIT;
# Kill and restart
drop procedure insert_t1;
drop table t1;

View File

@@ -20,6 +20,5 @@ call mtr.add_suppression("InnoDB: A copy of page \[page id: space=[0-9]+, page n
START TRANSACTION;
CALL insert_t1(5000);
COMMIT;
# Kill and restart
drop procedure insert_t1;
drop table t1;

View File

@@ -1,41 +0,0 @@
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
create procedure insert_t1(IN total int)
begin
declare i int default 1;
while (i <= total) DO
insert into t1 values (i, Point(i, i));
set i = i + 1;
end while;
end|
CALL insert_t1(5000);
select count(*) from t1;
count(*)
5000
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
truncate table t1;
CALL insert_t1(10000);
select count(*) from t1;
count(*)
10000
drop index c2 on t1;
create spatial index idx on t1(c2);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) DEFAULT NULL,
`c2` geometry NOT NULL,
SPATIAL KEY `idx` (`c2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
truncate table t1;
call mtr.add_suppression("InnoDB: page [0-9]+ in the doublewrite buffer is not within space bounds.*");
START TRANSACTION;
CALL insert_t1(5000);
COMMIT;
# Kill and restart
drop procedure insert_t1;
drop table t1;

View File

@@ -18,7 +18,6 @@ end while;
end|
CALL insert_t1(367);
COMMIT;
# Kill and restart
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
@@ -29,7 +28,6 @@ CALL update_t1(367);
SET @poly1 = ST_GeomFromText('POLYGON((10000 10000, 10000 10350, 10350 10350, 10350 10000, 10000 10000))');
delete from t1 where ST_Contains(@poly1, c2);
COMMIT;
# Kill and restart
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK

View File

@@ -53,7 +53,6 @@ COMMIT;
INSERT INTO t_wl6455 VALUES(11, POINT(11,11));
BEGIN;
INSERT INTO t_wl6455 VALUES(1, POINT(1,1));
# Kill and restart
CHECK TABLE t_wl6455;
Table Op Msg_type Msg_text
test.t_wl6455 check status OK

View File

@@ -58,7 +58,8 @@ CALL insert_t1(5000);
COMMIT;
--source include/kill_and_restart_mysqld.inc
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
# Clean up.
drop procedure insert_t1;

View File

@@ -51,7 +51,8 @@ CALL insert_t1(5000);
COMMIT;
--source include/kill_and_restart_mysqld.inc
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
# Clean up.
drop procedure insert_t1;

View File

@@ -44,7 +44,8 @@ delimiter ;|
CALL insert_t1(367);
COMMIT;
--source include/kill_and_restart_mysqld.inc
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
# Check table.
check table t1;
@@ -63,7 +64,7 @@ SET @poly1 = ST_GeomFromText('POLYGON((10000 10000, 10000 10350, 10350 10350, 10
delete from t1 where ST_Contains(@poly1, c2);
COMMIT;
--source include/kill_and_restart_mysqld.inc
--source include/restart_mysqld.inc
# Check table.
check table t1;

View File

@@ -73,7 +73,8 @@ INSERT INTO t_wl6455 VALUES(11, POINT(11,11));
BEGIN;
INSERT INTO t_wl6455 VALUES(1, POINT(1,1));
--source include/kill_and_restart_mysqld.inc
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
CHECK TABLE t_wl6455;
SELECT ST_AsText(g) FROM t_wl6455;

View File

@@ -69,7 +69,7 @@ INSERT INTO t1 (a,b,c,d) VALUES
(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
EXPLAIN SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
id select_type table type possible_keys key key_len ref rows Extra
# # # # # NULL # # # #
# # # # # b_c # # # #
SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
HEX(b+c)
10
@@ -98,7 +98,7 @@ INSERT INTO t1 (a,b,c,d) VALUES
(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
EXPLAIN SELECT DISTINCT a+0 FROM t1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
# # # # # NULL # # # #
# # # # # a # # # #
SELECT DISTINCT a+0 FROM t1 ORDER BY a;
a+0
0

View File

@@ -1878,6 +1878,18 @@ SELECT _utf8 0x7E, _utf8 X'7E', _utf8 B'01111110';
let $ctype_unescape_combinations=selected;
--source include/ctype_unescape.inc
--echo #
--echo # MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
--echo #
SET NAMES utf8;
SELECT CHAR(0xDF USING latin1);
CREATE OR REPLACE VIEW v1 AS SELECT CHAR(0xDF USING latin1) AS c;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;
--echo #
--echo # End of 10.0 tests
--echo #

View File

@@ -1922,6 +1922,24 @@ INSERT IGNORE INTO t1 SELECT 'a 😁 b', 'a 😁 b';
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-8949: COLUMN_CREATE unicode name breakage
--echo #
SET NAMES utf8mb4;
SELECT COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
SELECT COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
SELECT COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E
as int);
CREATE TABLE t1 AS SELECT
COLUMN_LIST(COLUMN_CREATE('a',1)),
COLUMN_JSON(COLUMN_CREATE('b',1));
SHOW CREATE TABLE t1;
DROP TABLE t1;
SET NAMES default;
--echo #
--echo # End of 10.0 tests
--echo #

View File

@@ -1809,6 +1809,18 @@ set global max_allowed_packet=default;
--echo # End of 5.6 tests
--echo #
--echo #
--echo # Start of 10.0 tests
--echo #
--echo #
--echo # MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
--echo #
EXPLAIN EXTENDED SELECT CHAR(0xDF USING latin1);
EXPLAIN EXTENDED SELECT CHAR(0xDF USING `binary`);
EXPLAIN EXTENDED SELECT CHAR(0xDF);
--echo #
--echo # Start of 10.1 tests
--echo #
@@ -1853,6 +1865,15 @@ SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64(
SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64("Yq==") OR f2= from_base64("YQ=="));
DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #
--echo #
--echo # Start of 10.3 tests
--echo #
--echo #
--echo # MDEV-12685 Oracle-compatible function CHR()
--echo #
@@ -1864,15 +1885,6 @@ select charset(chr(14844588)), length(chr(14844588)),char_length(chr(14844588));
drop database mysqltest1;
use test;
--echo #
--echo # End of 10.1 tests
--echo #
--echo #
--echo # Start of 10.3 tests
--echo #
--echo #
--echo # MDEV-12592 Illegal mix of collations with the HEX function
--echo #

View File

@@ -143,3 +143,22 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c1);
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
DROP VIEW v1;
DROP TABLE t1;
--echo #
--echo # MDEV-14628 Wrong autoinc value assigned by LOAD XML in the NO_AUTO_VALUE_ON_ZERO mode
--echo #
SET sql_mode=NO_AUTO_VALUE_ON_ZERO;
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT);
LOAD XML INFILE '../../std_data/loaddata/mdev14628a.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
SELECT * FROM t1 ORDER BY b;
DROP TABLE t1;
SET sql_mode=DEFAULT;
SET sql_mode='';
CREATE TABLE t1 (id INT, g GEOMETRY NOT NULL);
--error ER_WARN_NULL_TO_NOTNULL
LOAD XML INFILE '../../std_data/loaddata/mdev14628b.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
SELECT * FROM t1;
DROP TABLE t1;
SET sql_mode=DEFAULT;

View File

@@ -4183,8 +4183,7 @@ mariadb_dyncol_json_internal(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json,
}
else
{
if ((rc= mariadb_dyncol_val_str(json, &val,
&my_charset_utf8_general_ci, '"')) < 0)
if ((rc= mariadb_dyncol_val_str(json, &val, DYNCOL_UTF, '"')) < 0)
goto err;
}
}

View File

@@ -274,7 +274,7 @@ void thr_end_alarm(thr_alarm_t *alarmed)
/*
Come here when some alarm in queue is due.
Mark all alarms with are finnished in list.
Shedule alarms to be sent again after 1-10 sec (many alarms at once)
Schedule alarms to be sent again after 1-10 sec (many alarms at once)
If alarm_aborted is set then all alarms are given and resent
every second.
*/
@@ -426,7 +426,7 @@ void end_thr_alarm(my_bool free_structures)
if (alarm_aborted != 1) /* If memory not freed */
{
mysql_mutex_lock(&LOCK_alarm);
DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements));
DBUG_PRINT("info",("Rescheduling %d waiting alarms",alarm_queue.elements));
alarm_aborted= -1; /* mark aborted */
if (alarm_queue.elements || (alarm_thread_running && free_structures))
{

View File

@@ -1253,6 +1253,20 @@ warn:
}
bool Field::load_data_set_null(THD *thd)
{
reset();
set_null();
if (!maybe_null())
{
if (this != table->next_number_field)
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_NULL_TO_NOTNULL, 1);
}
set_has_explicit_value(); // Do not auto-update this field
return false;
}
/**
Numeric fields base class constructor.
*/
@@ -5152,6 +5166,27 @@ int Field_timestamp::set_time()
return 0;
}
bool Field_timestamp::load_data_set_null(THD *thd)
{
if (!maybe_null())
{
/*
Timestamp fields that are NOT NULL are autoupdated if there is no
corresponding value in the data file.
*/
set_time();
}
else
{
reset();
set_null();
}
set_has_explicit_value(); // Do not auto-update this field
return false;
}
#ifdef NOT_USED
static void store_native(ulonglong num, uchar *to, uint bytes)
{
@@ -8734,6 +8769,22 @@ bool Field_geom::can_optimize_range(const Item_bool_func *cond,
return item->cmp_type() == STRING_RESULT;
}
bool Field_geom::load_data_set_null(THD *thd)
{
Field_blob::reset();
if (!maybe_null())
{
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field_name.str,
thd->get_stmt_da()->current_row_for_warning());
return true;
}
set_null();
set_has_explicit_value(); // Do not auto-update this field
return false;
}
#endif /*HAVE_SPATIAL*/
/****************************************************************************

View File

@@ -1161,6 +1161,8 @@ public:
{ if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
inline bool maybe_null(void) const
{ return null_ptr != 0 || table->maybe_null; }
// Set to NULL on LOAD DATA or LOAD XML
virtual bool load_data_set_null(THD *thd);
/* @return true if this field is NULL-able (even if temporarily) */
inline bool real_maybe_null(void) const { return null_ptr != 0; }
@@ -2457,6 +2459,7 @@ public:
{
return get_equal_const_item_datetime(thd, ctx, const_item);
}
bool load_data_set_null(THD *thd);
uint size_of() const { return sizeof(*this); }
};
@@ -3649,6 +3652,7 @@ public:
but the underlying blob must still be reset.
*/
int reset(void) { return Field_blob::reset() || !maybe_null(); }
bool load_data_set_null(THD *thd);
geometry_type get_geometry_type() { return geom_type; };
static geometry_type geometry_type_merge(geometry_type, geometry_type);

View File

@@ -6960,20 +6960,20 @@ longlong Item_func_dyncol_exists::val_int()
null_value= 1;
return 1;
}
if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci))
if (my_charset_same(nm->charset(), DYNCOL_UTF))
{
buf.str= (char *) nm->ptr();
buf.length= nm->length();
}
else
{
uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1;
uint strlen= nm->length() * DYNCOL_UTF->mbmaxlen + 1;
uint dummy_errors;
buf.str= (char *) current_thd->alloc(strlen);
if (buf.str)
{
buf.length=
copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci,
copy_and_convert(buf.str, strlen, DYNCOL_UTF,
nm->ptr(), nm->length(), nm->charset(),
&dummy_errors);
}

View File

@@ -2918,6 +2918,20 @@ String *Item_func_make_set::val_str(String *str)
}
void Item_func_char::print(String *str, enum_query_type query_type)
{
str->append(Item_func_char::func_name());
str->append('(');
print_args(str, 0, query_type);
if (collation.collation != &my_charset_bin)
{
str->append(C_STRING_WITH_LEN(" using "));
str->append(collation.collation->csname);
}
str->append(')');
}
String *Item_func_char::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
@@ -4517,20 +4531,19 @@ bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg)
if (res)
{
// guaranty UTF-8 string for names
if (my_charset_same(res->charset(), &my_charset_utf8_general_ci))
if (my_charset_same(res->charset(), DYNCOL_UTF))
{
keys_str[i].length= res->length();
keys_str[i].str= thd->strmake(res->ptr(), res->length());
}
else
{
uint strlen= res->length() * my_charset_utf8_general_ci.mbmaxlen + 1;
uint strlen= res->length() * DYNCOL_UTF->mbmaxlen + 1;
uint dummy_errors;
char *str= (char *) thd->alloc(strlen);
if (str)
if (char *str= (char *) thd->alloc(strlen))
{
keys_str[i].length=
copy_and_convert(str, strlen, &my_charset_utf8_general_ci,
copy_and_convert(str, strlen, DYNCOL_UTF,
res->ptr(), res->length(), res->charset(),
&dummy_errors);
keys_str[i].str= str;
@@ -4750,9 +4763,10 @@ String *Item_func_dyncol_json::val_str(String *str)
char *ptr;
size_t length, alloc_length;
dynstr_reassociate(&json, &ptr, &length, &alloc_length);
str->reset(ptr, length, alloc_length, &my_charset_utf8_general_ci);
str->reset(ptr, length, alloc_length, DYNCOL_UTF);
null_value= FALSE;
}
str->set_charset(DYNCOL_UTF);
return str;
null:
@@ -4852,20 +4866,20 @@ bool Item_dyncol_get::get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val,
return 1;
}
if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci))
if (my_charset_same(nm->charset(), DYNCOL_UTF))
{
buf.str= (char *) nm->ptr();
buf.length= nm->length();
}
else
{
uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1;
uint strlen= nm->length() * DYNCOL_UTF->mbmaxlen + 1;
uint dummy_errors;
buf.str= (char *) thd->alloc(strlen);
if (buf.str)
{
buf.length=
copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci,
copy_and_convert(buf.str, strlen, DYNCOL_UTF,
nm->ptr(), nm->length(), nm->charset(),
&dummy_errors);
}
@@ -5289,7 +5303,6 @@ String *Item_func_dyncol_list::val_str(String *str)
goto null;
str->length(0);
str->set_charset(&my_charset_utf8_general_ci);
for (i= 0; i < count; i++)
{
append_identifier(current_thd, str, names[i].str, names[i].length);
@@ -5299,6 +5312,7 @@ String *Item_func_dyncol_list::val_str(String *str)
null_value= FALSE;
if (names)
my_free(names);
str->set_charset(DYNCOL_UTF);
return str;
null:

View File

@@ -978,6 +978,7 @@ public:
max_length= arg_count * 4;
}
const char *func_name() const { return "char"; }
void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_char>(thd, this); }
};
@@ -1585,14 +1586,14 @@ public:
class Item_func_dyncol_json: public Item_str_func
{
public:
Item_func_dyncol_json(THD *thd, Item *str): Item_str_func(thd, str) {}
Item_func_dyncol_json(THD *thd, Item *str): Item_str_func(thd, str)
{collation.set(DYNCOL_UTF);}
const char *func_name() const{ return "column_json"; }
String *val_str(String *);
void fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
collation.set(&my_charset_bin);
decimals= 0;
}
Item *get_copy(THD *thd)
@@ -1645,7 +1646,8 @@ public:
class Item_func_dyncol_list: public Item_str_func
{
public:
Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str) {};
Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str)
{collation.set(DYNCOL_UTF);}
void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; };
const char *func_name() const{ return "column_list"; }
String *val_str(String *);

View File

@@ -1015,7 +1015,6 @@ continue_loop:;
}
static int
read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields_vars, List<Item> &set_fields,
@@ -1094,28 +1093,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
else
{
Field *field= real_item->field;
if (field->reset())
{
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name.str,
thd->get_stmt_da()->current_row_for_warning());
DBUG_ASSERT(real_item->field->table == table);
if (real_item->field->load_data_set_null(thd))
DBUG_RETURN(1);
}
field->set_null();
if (!field->maybe_null())
{
/*
Timestamp fields that are NOT NULL are autoupdated if there is no
corresponding value in the data file.
*/
if (field->type() == MYSQL_TYPE_TIMESTAMP)
field->set_time();
else if (field != table->next_number_field)
field->set_warning(Sql_condition::WARN_LEVEL_WARN,
ER_WARN_NULL_TO_NOTNULL, 1);
}
/* Do not auto-update this field. */
field->set_has_explicit_value();
}
continue;
@@ -1262,6 +1242,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
for ( ; ; it.rewind())
{
bool err;
if (thd->killed)
{
thd->send_kill_message();
@@ -1313,21 +1294,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
else
{
Field *field= real_item->field;
field->reset();
field->set_null();
if (field == table->next_number_field)
table->auto_increment_field_not_null= TRUE;
if (!field->maybe_null())
{
if (field->type() == FIELD_TYPE_TIMESTAMP)
field->set_time();
else if (field != table->next_number_field)
field->set_warning(Sql_condition::WARN_LEVEL_WARN,
ER_WARN_NULL_TO_NOTNULL, 1);
}
/* Do not auto-update this field. */
field->set_has_explicit_value();
DBUG_ASSERT(real_item->field->table == table);
if (real_item->field->load_data_set_null(thd))
DBUG_RETURN(1);
}
continue;
}
@@ -1361,39 +1330,8 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
skip_lines--;
continue;
}
if (item)
{
/* Have not read any field, thus input file is simply ended */
if (item == fields_vars.head())
break;
for ( ; item; item= it++)
{
Item_field *real_item= item->field_for_view_update();
if (item->type() == Item::STRING_ITEM)
((Item_user_var_as_out_param *)item)->set_null_value(cs);
else if (!real_item)
{
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name.str);
DBUG_RETURN(1);
}
else
{
/*
QQ: We probably should not throw warning for each field.
But how about intention to always have the same number
of warnings in THD::cuted_fields (and get rid of cuted_fields
in the end ?)
*/
thd->cuted_fields++;
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_TOO_FEW_RECORDS,
ER_THD(thd, ER_WARN_TOO_FEW_RECORDS),
thd->get_stmt_da()->current_row_for_warning());
}
}
}
DBUG_ASSERT(!item);
if (thd->killed ||
fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values,
@@ -1410,7 +1348,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(-1);
}
if (write_record(thd, table, &info))
err= write_record(thd, table, &info);
table->auto_increment_field_not_null= false;
if (err)
DBUG_RETURN(1);
/*

View File

@@ -2791,6 +2791,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
{
thd_info->proc_info= "Busy";
thd_info->progress= 0.0;
thd_info->db= "";
}
thd_info->state_info= thread_state_info(tmp);

View File

@@ -489,62 +489,4 @@ ha_validate(
return(ok);
}
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
/*************************************************************//**
Prints info of a hash table. */
void
ha_print_info(
/*==========*/
FILE* file, /*!< in: file where to print */
hash_table_t* table) /*!< in: hash table */
{
#ifdef UNIV_DEBUG
/* Some of the code here is disabled for performance reasons in production
builds, see http://bugs.mysql.com/36941 */
#define PRINT_USED_CELLS
#endif /* UNIV_DEBUG */
#ifdef PRINT_USED_CELLS
hash_cell_t* cell;
ulint cells = 0;
ulint i;
#endif /* PRINT_USED_CELLS */
ulint n_bufs;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#ifdef PRINT_USED_CELLS
for (i = 0; i < hash_get_n_cells(table); i++) {
cell = hash_get_nth_cell(table, i);
if (cell->node) {
cells++;
}
}
#endif /* PRINT_USED_CELLS */
fprintf(file, "Hash table size %lu",
(ulong) hash_get_n_cells(table));
#ifdef PRINT_USED_CELLS
fprintf(file, ", used cells %lu", (ulong) cells);
#endif /* PRINT_USED_CELLS */
if (table->heaps == NULL && table->heap != NULL) {
/* This calculation is intended for the adaptive hash
index: how many buffer frames we have reserved? */
n_bufs = UT_LIST_GET_LEN(table->heap->base) - 1;
if (table->heap->free_block) {
n_bufs++;
}
fprintf(file, ", node heap has %lu buffer(s)\n",
(ulong) n_bufs);
}
}
#endif /* BTR_CUR_HASH_ADAPT */

View File

@@ -3746,8 +3746,7 @@ innobase_init(
/* Currently, Galera does not support VATS lock schedule algorithm. */
if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&& global_system_variables.wsrep_on) {
ib::info() << "In Galera environment Variance-Aware-Transaction-Sheduling Algorithm"
" is not supported. Falling back to First-Come-First-Served order. ";
ib::info() << "For Galera, using innodb_lock_schedule_algorithm=fcfs";
innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
}
#endif /* WITH_WSREP */

View File

@@ -198,13 +198,6 @@ ha_validate(
ulint start_index, /*!< in: start index */
ulint end_index); /*!< in: end index */
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
/*************************************************************//**
Prints info of a hash table. */
void
ha_print_info(
/*==========*/
FILE* file, /*!< in: file where to print */
hash_table_t* table); /*!< in: hash table */
/** The hash table external chain node */
struct ha_node_t {

View File

@@ -380,9 +380,6 @@ struct que_thr_t{
UT_LIST_NODE_T(que_thr_t)
thrs; /*!< list of thread nodes of the fork
node */
UT_LIST_NODE_T(que_thr_t)
trx_thrs; /*!< lists of threads in wait list of
the trx */
UT_LIST_NODE_T(que_thr_t)
queue; /*!< list of runnable thread nodes in
the server task queue */

View File

@@ -33,7 +33,8 @@ Created 3/26/1996 Heikki Tuuri
#include "mtr0mtr.h"
#include "trx0sys.h"
extern bool trx_rollback_or_clean_is_active;
extern bool trx_rollback_or_clean_is_active;
extern const trx_t* trx_roll_crash_recv_trx;
/*******************************************************************//**
Determines if this transaction is rolling back an incomplete transaction
@@ -62,6 +63,10 @@ trx_undo_rec_t*
trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap)
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Report progress when rolling back a row of a recovered transaction.
@return whether the rollback should be aborted due to pending shutdown */
bool
trx_roll_must_shutdown();
/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was

View File

@@ -520,7 +520,7 @@ row_quiesce_table_start(
ut_ad(fil_space_get(table->space) != NULL);
ib::info() << "Sync to disk of " << table->name << " started.";
if (trx_purge_state() != PURGE_STATE_DISABLED) {
if (srv_undo_sources) {
trx_purge_stop();
}
@@ -603,7 +603,7 @@ row_quiesce_table_complete(
ib::info() << "Deleting the meta-data file '" << cfg_name << "'";
}
if (trx_purge_state() != PURGE_STATE_DISABLED) {
if (srv_undo_sources) {
trx_purge_run();
}

View File

@@ -1192,7 +1192,16 @@ close_table:
if (!row_undo_search_clust_to_pcur(node)) {
/* As long as this rolling-back transaction exists,
the PRIMARY KEY value pointed to by the undo log
record must exist. But, it is possible that the record
record should exist.
However, if InnoDB is killed during a rollback, or
shut down during the rollback of recovered
transactions, then after restart we may try to roll
back some of the same undo log records again, because
trx_roll_try_truncate() is not being invoked after
every undo log record.
It is also possible that the record
was not modified yet (the DB_ROLL_PTR does not match
node->roll_ptr) and thus there is nothing to roll back.
@@ -1200,8 +1209,11 @@ close_table:
record after successfully acquiring an exclusive lock
on the the clustered index record. That lock will not
be released before the transaction is committed or
fully rolled back. */
ut_ad(node->pcur.btr_cur.low_match == node->ref->n_fields);
fully rolled back. (Exception: if the server was
killed, restarted, and shut down again before the
rollback of the recovered transaction was completed,
it is possible that the transaction was partially
rolled back and locks released.) */
goto close_table;
}

View File

@@ -343,6 +343,13 @@ row_undo_step(
ut_ad(que_node_get_type(node) == QUE_NODE_UNDO);
if (UNIV_UNLIKELY(trx == trx_roll_crash_recv_trx)
&& trx_roll_must_shutdown()) {
/* Shutdown has been initiated. */
trx->error_state = DB_INTERRUPTED;
return(NULL);
}
err = row_undo(node, thr);
trx->error_state = err;

View File

@@ -1301,9 +1301,28 @@ srv_printf_innodb_monitor(
#ifdef BTR_CUR_HASH_ADAPT
for (ulint i = 0; i < btr_ahi_parts; ++i) {
rw_lock_s_lock(btr_search_latches[i]);
ha_print_info(file, btr_search_sys->hash_tables[i]);
rw_lock_s_unlock(btr_search_latches[i]);
const hash_table_t* table = btr_search_sys->hash_tables[i];
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
/* this is only used for buf_pool->page_hash */
ut_ad(!table->heaps);
/* this is used for the adaptive hash index */
ut_ad(table->heap);
const mem_heap_t* heap = table->heap;
/* The heap may change during the following call,
so the data displayed may be garbage. We intentionally
avoid acquiring btr_search_latches[] so that the
diagnostic output will not stop here even in case another
thread hangs while holding btr_search_latches[].
This should be safe from crashes, because
table->heap will be pointing to the same object
for the full lifetime of the server. Even during
btr_search_disable() the heap will stay valid. */
fprintf(file, "Hash table size " ULINTPF
", node heap has " ULINTPF " buffer(s)\n",
table->n_cells, heap->base.count - !heap->free_block);
}
fprintf(file,
@@ -2831,6 +2850,9 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
purge_sys->running = false;
/* Ensure that the wait in trx_purge_stop() will terminate. */
os_event_set(purge_sys->event);
rw_lock_x_unlock(&purge_sys->latch);
#ifdef UNIV_DEBUG_THREAD_CREATION

View File

@@ -2618,8 +2618,6 @@ files_checked:
srv_start_state_set(SRV_START_STATE_MASTER);
}
srv_is_being_started = false;
if (!srv_read_only_mode && srv_operation == SRV_OPERATION_NORMAL
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND) {
@@ -2647,6 +2645,8 @@ files_checked:
purge_sys->state = PURGE_STATE_DISABLED;
}
srv_is_being_started = false;
if (!srv_read_only_mode) {
/* wake main loop of page cleaner up */
os_event_set(buf_flush_event);

View File

@@ -1724,52 +1724,48 @@ void
trx_purge_stop(void)
/*================*/
{
ut_a(srv_n_purge_threads > 0);
rw_lock_x_lock(&purge_sys->latch);
const int64_t sig_count = os_event_reset(purge_sys->event);
const purge_state_t state = purge_sys->state;
ut_a(state == PURGE_STATE_RUN || state == PURGE_STATE_STOP);
++purge_sys->n_stop;
if (state == PURGE_STATE_RUN) {
switch (purge_sys->state) {
case PURGE_STATE_INIT:
case PURGE_STATE_DISABLED:
ut_error;
case PURGE_STATE_EXIT:
/* Shutdown must have been initiated during
FLUSH TABLES FOR EXPORT. */
ut_ad(!srv_undo_sources);
unlock:
rw_lock_x_unlock(&purge_sys->latch);
break;
case PURGE_STATE_STOP:
ut_ad(srv_n_purge_threads > 0);
++purge_sys->n_stop;
purge_sys->state = PURGE_STATE_STOP;
if (!purge_sys->running) {
goto unlock;
}
ib::info() << "Waiting for purge to stop";
do {
rw_lock_x_unlock(&purge_sys->latch);
os_thread_sleep(10000);
rw_lock_x_lock(&purge_sys->latch);
} while (purge_sys->running);
goto unlock;
case PURGE_STATE_RUN:
ut_ad(srv_n_purge_threads > 0);
++purge_sys->n_stop;
ib::info() << "Stopping purge";
/* We need to wakeup the purge thread in case it is suspended,
so that it can acknowledge the state change. */
const int64_t sig_count = os_event_reset(purge_sys->event);
purge_sys->state = PURGE_STATE_STOP;
srv_purge_wakeup();
}
purge_sys->state = PURGE_STATE_STOP;
if (state != PURGE_STATE_STOP) {
rw_lock_x_unlock(&purge_sys->latch);
/* Wait for purge coordinator to signal that it
is suspended. */
os_event_wait_low(purge_sys->event, sig_count);
} else {
bool once = true;
/* Wait for purge to signal that it has actually stopped. */
while (purge_sys->running) {
if (once) {
ib::info() << "Waiting for purge to stop";
once = false;
}
rw_lock_x_unlock(&purge_sys->latch);
os_thread_sleep(10000);
rw_lock_x_lock(&purge_sys->latch);
}
rw_lock_x_unlock(&purge_sys->latch);
}
MONITOR_INC_VALUE(MONITOR_PURGE_STOP_COUNT, 1);
@@ -1784,8 +1780,12 @@ trx_purge_run(void)
rw_lock_x_lock(&purge_sys->latch);
switch (purge_sys->state) {
case PURGE_STATE_INIT:
case PURGE_STATE_EXIT:
/* Shutdown must have been initiated during
FLUSH TABLES FOR EXPORT. */
ut_ad(!srv_undo_sources);
break;
case PURGE_STATE_INIT:
case PURGE_STATE_DISABLED:
ut_error;

View File

@@ -24,8 +24,10 @@ Transaction rollback
Created 3/26/1996 Heikki Tuuri
*******************************************************/
#include "ha_prototypes.h"
#include "my_config.h"
#include <my_systemd.h>
#include "ha_prototypes.h"
#include "trx0roll.h"
#include <mysql/service_wsrep.h>
@@ -56,14 +58,7 @@ static const ulint TRX_ROLL_TRUNC_THRESHOLD = 1;
bool trx_rollback_or_clean_is_active;
/** In crash recovery, the current trx to be rolled back; NULL otherwise */
static const trx_t* trx_roll_crash_recv_trx = NULL;
/** In crash recovery we set this to the undo n:o of the current trx to be
rolled back. Then we can print how many % the rollback has progressed. */
static undo_no_t trx_roll_max_undo_no;
/** Auxiliary variable which tells the previous progress % we printed */
static ulint trx_roll_progress_printed_pct;
const trx_t* trx_roll_crash_recv_trx;
/****************************************************************//**
Finishes a transaction rollback. */
@@ -642,8 +637,6 @@ trx_rollback_active(
que_thr_t* thr;
roll_node_t* roll_node;
dict_table_t* table;
int64_t rows_to_undo;
const char* unit = "";
ibool dictionary_locked = FALSE;
heap = mem_heap_create(512);
@@ -662,28 +655,8 @@ trx_rollback_active(
ut_a(thr == que_fork_start_command(fork));
trx_sys_mutex_enter();
trx_roll_crash_recv_trx = trx;
trx_roll_max_undo_no = trx->undo_no;
trx_roll_progress_printed_pct = 0;
rows_to_undo = trx_roll_max_undo_no;
trx_sys_mutex_exit();
if (rows_to_undo > 1000000000) {
rows_to_undo = rows_to_undo / 1000000;
unit = "M";
}
const trx_id_t trx_id = trx_get_id_for_print(trx);
ib::info() << "Rolling back trx with id " << trx_id << ", "
<< rows_to_undo << unit << " rows to undo";
if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
row_mysql_lock_data_dictionary(trx);
dictionary_locked = TRUE;
@@ -694,6 +667,17 @@ trx_rollback_active(
que_run_threads(roll_node->undo_thr);
if (trx->error_state != DB_SUCCESS) {
ut_ad(trx->error_state == DB_INTERRUPTED);
ut_ad(!srv_is_being_started);
ut_ad(!srv_undo_sources);
ut_ad(srv_fast_shutdown);
ut_ad(!dictionary_locked);
que_graph_free(static_cast<que_t*>(
roll_node->undo_thr->common.parent));
goto func_exit;
}
trx_rollback_finish(thr_get_trx(roll_node->undo_thr));
/* Free the memory reserved by the undo graph */
@@ -725,11 +709,13 @@ trx_rollback_active(
}
}
func_exit:
if (dictionary_locked) {
row_mysql_unlock_data_dictionary(trx);
}
ib::info() << "Rollback of trx with id " << trx_id << " completed";
ib::info() << "Rollback of trx with id " << ib::hex(trx->id)
<< " completed";
mem_heap_free(heap);
@@ -747,7 +733,7 @@ ibool
trx_rollback_resurrected(
/*=====================*/
trx_t* trx, /*!< in: transaction to rollback or clean */
ibool all) /*!< in: FALSE=roll back dictionary transactions;
ibool* all) /*!< in/out: FALSE=roll back dictionary transactions;
TRUE=roll back all non-PREPARED transactions */
{
ut_ad(trx_sys_mutex_own());
@@ -758,40 +744,102 @@ trx_rollback_resurrected(
to accidentally clean up a non-recovered transaction here. */
trx_mutex_enter(trx);
bool is_recovered = trx->is_recovered;
trx_state_t state = trx->state;
trx_mutex_exit(trx);
if (!is_recovered) {
if (!trx->is_recovered) {
func_exit:
trx_mutex_exit(trx);
return(FALSE);
}
switch (state) {
switch (trx->state) {
case TRX_STATE_COMMITTED_IN_MEMORY:
trx_mutex_exit(trx);
trx_sys_mutex_exit();
ib::info() << "Cleaning up trx with id "
<< trx_get_id_for_print(trx);
ib::info() << "Cleaning up trx with id " << ib::hex(trx->id);
trx_cleanup_at_db_startup(trx);
trx_free_resurrected(trx);
return(TRUE);
case TRX_STATE_ACTIVE:
if (all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
if (!srv_is_being_started
&& !srv_undo_sources && srv_fast_shutdown) {
fake_prepared:
trx->state = TRX_STATE_PREPARED;
trx_sys->n_prepared_trx++;
trx_sys->n_prepared_recovered_trx++;
*all = FALSE;
goto func_exit;
}
trx_mutex_exit(trx);
if (*all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
trx_sys_mutex_exit();
trx_rollback_active(trx);
if (trx->error_state != DB_SUCCESS) {
ut_ad(trx->error_state == DB_INTERRUPTED);
trx->error_state = DB_SUCCESS;
ut_ad(!srv_undo_sources);
ut_ad(srv_fast_shutdown);
mutex_enter(&trx_sys->mutex);
trx_mutex_enter(trx);
goto fake_prepared;
}
trx_free_for_background(trx);
return(TRUE);
}
return(FALSE);
case TRX_STATE_PREPARED:
return(FALSE);
goto func_exit;
case TRX_STATE_NOT_STARTED:
case TRX_STATE_FORCED_ROLLBACK:
break;
}
ut_error;
return(FALSE);
goto func_exit;
}
/** Report progress when rolling back a row of a recovered transaction.
@return whether the rollback should be aborted due to pending shutdown */
bool
trx_roll_must_shutdown()
{
const trx_t* trx = trx_roll_crash_recv_trx;
ut_ad(trx);
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
ut_ad(trx->in_rollback);
if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE
&& !srv_is_being_started
&& !srv_undo_sources && srv_fast_shutdown) {
return true;
}
ib_time_t time = ut_time();
mutex_enter(&trx_sys->mutex);
mutex_enter(&recv_sys->mutex);
if (recv_sys->report(time)) {
ulint n_trx = 0, n_rows = 0;
for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
t != NULL;
t = UT_LIST_GET_NEXT(trx_list, t)) {
assert_trx_in_rw_list(t);
if (t->is_recovered
&& trx_state_eq(t, TRX_STATE_ACTIVE)) {
n_trx++;
n_rows += t->undo_no;
}
}
ib::info() << "To roll back: " << n_trx << " transactions, "
<< n_rows << " rows";
sd_notifyf(0, "STATUS=To roll back: " ULINTPF " transactions, "
ULINTPF " rows", n_trx, n_rows);
}
mutex_exit(&recv_sys->mutex);
mutex_exit(&trx_sys->mutex);
return false;
}
/*******************************************************************//**
@@ -836,17 +884,11 @@ trx_rollback_or_clean_recovered(
assert_trx_in_rw_list(trx);
if (srv_shutdown_state != SRV_SHUTDOWN_NONE
&& srv_fast_shutdown != 0) {
all = FALSE;
break;
}
/* If this function does a cleanup or rollback
then it will release the trx_sys->mutex, therefore
we need to reacquire it before retrying the loop. */
if (trx_rollback_resurrected(trx, all)) {
if (trx_rollback_resurrected(trx, &all)) {
trx_sys_mutex_enter();
@@ -1056,27 +1098,6 @@ trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap)
ut_ad(trx_roll_check_undo_rec_ordering(
undo_no, undo->rseg->space, trx));
/* We print rollback progress info if we are in a crash recovery
and the transaction has at least 1000 row operations to undo. */
if (trx == trx_roll_crash_recv_trx && trx_roll_max_undo_no > 1000) {
ulint progress_pct = 100 - (ulint)
((undo_no * 100) / trx_roll_max_undo_no);
if (progress_pct != trx_roll_progress_printed_pct) {
if (trx_roll_progress_printed_pct == 0) {
fprintf(stderr,
"\nInnoDB: Progress in percents:"
" %lu", (ulong) progress_pct);
} else {
fprintf(stderr,
" %lu", (ulong) progress_pct);
}
fflush(stderr);
trx_roll_progress_printed_pct = progress_pct;
}
}
trx->undo_no = undo_no;
trx->undo_rseg_space = undo->rseg->space;
mutex_exit(&trx->undo_mutex);

View File

@@ -1602,10 +1602,14 @@ trx_undo_free_prepared(
/* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
trx->is_recovered=false */
trx->is_recovered=false and
trx->state = TRX_STATE_COMMITTED_IN_MEMORY,
also for transactions that we faked
to TRX_STATE_PREPARED in trx_rollback_resurrected(). */
ut_a(!srv_was_started
|| srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
|| srv_fast_shutdown);
break;
default:
ut_error;
@@ -1628,10 +1632,14 @@ trx_undo_free_prepared(
/* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
trx->is_recovered=false */
trx->is_recovered=false and
trx->state = TRX_STATE_COMMITTED_IN_MEMORY,
also for transactions that we faked
to TRX_STATE_PREPARED in trx_rollback_resurrected(). */
ut_a(!srv_was_started
|| srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
|| srv_fast_shutdown);
break;
default:
ut_error;

View File

@@ -6342,7 +6342,6 @@ my_bool translog_write_record(LSN *lsn,
short_trid, &parts, trn, hook_arg);
break;
case LOGRECTYPE_NOT_ALLOWED:
DBUG_ASSERT(0);
default:
DBUG_ASSERT(0);
rc= 1;

View File

@@ -14,6 +14,7 @@ lock_concurrent : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bog
optimize_table : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bogus error message
repair_table : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bogus error message
select_high_prio : Not supported
show_engine : SHOW ENGINE produces different number of lines depending on previous tests
show_table_status : MDEV-13152 - Indeterministic row number in SHOW TABLE STATUS on RocksDB table
tbl_opt_data_dir : Not supported
tbl_opt_index_dir : Not supported

View File

@@ -0,0 +1,20 @@
--- suite/storage_engine/type_bit_indexes.result 2017-12-12 20:34:34.000000000 +0200
+++ suite/storage_engine/type_bit_indexes.reject 2017-12-12 20:35:24.539330056 +0200
@@ -69,7 +69,7 @@
(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
EXPLAIN SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
id select_type table type possible_keys key key_len ref rows Extra
-# # # # # b_c # # # #
+# # # # # NULL # # # #
SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
HEX(b+c)
10
@@ -98,7 +98,7 @@
(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
EXPLAIN SELECT DISTINCT a+0 FROM t1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
-# # # # # a # # # #
+# # # # # NULL # # # #
SELECT DISTINCT a+0 FROM t1 ORDER BY a;
a+0
0

View File

@@ -0,0 +1,11 @@
--- suite/storage_engine/type_enum_indexes.result 2017-03-12 04:38:50.000000000 +0200
+++ suite/storage_engine/type_enum_indexes.reject 2017-12-12 20:36:47.455331726 +0200
@@ -30,7 +30,7 @@
t1 0 a_b 2 b # # NULL NULL # #
EXPLAIN SELECT a FROM t1 WHERE b > 'test2' ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
-# # # # # a_b # # # #
+# # # # # NULL # # # #
SELECT a FROM t1 WHERE b > 'test2' ORDER BY a;
a
Africa

View File

@@ -0,0 +1,20 @@
--- suite/storage_engine/type_set_indexes.result 2017-03-12 04:38:50.000000000 +0200
+++ suite/storage_engine/type_set_indexes.reject 2017-12-12 20:37:16.187332305 +0200
@@ -97,7 +97,7 @@
Warning 1265 Data truncated for column 'b' at row 7
EXPLAIN SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
id select_type table type possible_keys key key_len ref rows Extra
-# # # # # a # # # #
+# # # # # NULL # # # #
SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
a
Africa,Europe,Asia
@@ -124,7 +124,7 @@
Warning 1265 Data truncated for column 'b' at row 7
EXPLAIN SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a;
id select_type table type possible_keys key key_len ref rows Extra
-# # # # # b_a # # # #
+# # # # # NULL # # # #
SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a;
a b
test1,test3

View File

@@ -226,7 +226,6 @@ master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Binlog_checkpoint # # master-bin.000002
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
master-bin.000002 # Gtid # # GTID #-#-#
@@ -268,7 +267,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
slave-bin.000002 # Gtid # # GTID #-#-#
slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB
slave-bin.000002 # Gtid # # BEGIN GTID #-#-#

View File

@@ -222,7 +222,6 @@ master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Binlog_checkpoint # # master-bin.000002
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
master-bin.000002 # Gtid # # GTID #-#-#
@@ -260,7 +259,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
slave-bin.000002 # Gtid # # GTID #-#-#
slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB
slave-bin.000002 # Gtid # # BEGIN GTID #-#-#