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:
@@ -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}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
#
|
||||
#
|
||||
|
||||
@@ -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
|
||||
#
|
||||
#
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
4
mysql-test/std_data/loaddata/mdev14628a.xml
Normal file
4
mysql-test/std_data/loaddata/mdev14628a.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<list>
|
||||
<row a="1" b="bbb1"/>
|
||||
<row b="bbb2"/>
|
||||
</list>
|
||||
3
mysql-test/std_data/loaddata/mdev14628b.xml
Normal file
3
mysql-test/std_data/loaddata/mdev14628b.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<list>
|
||||
<row id="1"/>
|
||||
</list>
|
||||
64
mysql-test/suite/innodb/r/recovery_shutdown.result
Normal file
64
mysql-test/suite/innodb/r/recovery_shutdown.result
Normal 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;
|
||||
@@ -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
|
||||
|
||||
59
mysql-test/suite/innodb/t/recovery_shutdown.test
Normal file
59
mysql-test/suite/innodb/t/recovery_shutdown.test
Normal 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;
|
||||
@@ -1 +1 @@
|
||||
--innodb-open-files=13
|
||||
--innodb-open-files=20
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 #
|
||||
|
||||
@@ -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 #
|
||||
|
||||
@@ -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 #
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
51
sql/field.cc
51
sql/field.cc
@@ -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*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 #-#-#
|
||||
|
||||
@@ -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 #-#-#
|
||||
|
||||
Reference in New Issue
Block a user