Commit f82c8c69 authored by Davi Arnaut's avatar Davi Arnaut

Merge before pushing.

parents 3bdbfd70 19891fe9
...@@ -412,7 +412,10 @@ sub mtr_report_stats ($) { ...@@ -412,7 +412,10 @@ sub mtr_report_stats ($) {
# When trying to set lower_case_table_names = 2 # When trying to set lower_case_table_names = 2
# on a case sensitive file system. Bug#37402. # on a case sensitive file system. Bug#37402.
/lower_case_table_names was set to 2, even though your the file system '.*' is case sensitive. Now setting lower_case_table_names to 0 to avoid future problems./ /lower_case_table_names was set to 2, even though your the file system '.*' is case sensitive. Now setting lower_case_table_names to 0 to avoid future problems./ or
# this test is expected to print warnings
($testname eq 'main.innodb_bug39438')
) )
{ {
next; # Skip these lines next; # Skip these lines
......
...@@ -169,3 +169,413 @@ t1 CREATE TABLE `t1` ( ...@@ -169,3 +169,413 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`c1`) PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, 1);
DELETE FROM t1 WHERE c1 = 1;
INSERT INTO t1 VALUES (2,1);
INSERT INTO t1 VALUES (NULL,8);
SELECT * FROM t1;
c1 c2
2 1
3 8
DROP TABLE t1;
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, 1);
DELETE FROM t1 WHERE c1 = 1;
INSERT INTO t1 VALUES (2,1), (NULL, 8);
INSERT INTO t1 VALUES (NULL,9);
SELECT * FROM t1;
c1 c2
2 1
3 8
5 9
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL),(5),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
c1
5
10
110
250
310
INSERT INTO t1 VALUES (1000);
SET @@INSERT_ID=400;
INSERT INTO t1 VALUES(NULL),(NULL);
SELECT * FROM t1;
c1
5
10
110
250
310
400
410
1000
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(0);
SELECT * FROM t1;
c1
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
INSERT INTO t1 VALUES (-1), (NULL),(2),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
c1
-1
1
2
10
110
250
410
SET @@INSERT_ID=400;
INSERT INTO t1 VALUES(NULL),(NULL);
Got one of the listed errors
SELECT * FROM t1;
c1
-1
1
2
10
110
250
410
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
c1
-1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
INSERT INTO t1 VALUES (-2), (NULL),(2),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
c1
-2
-1
1
2
10
250
310
INSERT INTO t1 VALUES (1000);
SET @@INSERT_ID=400;
INSERT INTO t1 VALUES(NULL),(NULL);
SELECT * FROM t1;
c1
-2
-1
1
2
10
250
310
400
410
1000
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
SELECT * FROM t1;
c1
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
INSERT INTO t1 VALUES (-2);
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
INSERT INTO t1 VALUES (NULL);
INSERT INTO t1 VALUES (2);
INSERT INTO t1 VALUES (NULL);
INSERT INTO t1 VALUES (250);
INSERT INTO t1 VALUES (NULL);
SELECT * FROM t1;
c1
1
2
10
110
210
250
310
INSERT INTO t1 VALUES (1000);
SET @@INSERT_ID=400;
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES(NULL);
SELECT * FROM t1;
c1
1
2
10
110
210
250
310
400
1000
1010
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
SELECT * FROM t1;
c1
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
INSERT INTO t1 VALUES (-2),(NULL),(2),(NULL);
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
c1
1
2
10
110
210
250
410
INSERT INTO t1 VALUES (1000);
SET @@INSERT_ID=400;
INSERT INTO t1 VALUES(NULL),(NULL);
Got one of the listed errors
SELECT * FROM t1;
c1
1
2
10
110
210
250
410
1000
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (9223372036854775794);
SELECT * FROM t1;
c1
1
9223372036854775794
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 2
auto_increment_offset 10
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
SELECT * FROM t1;
c1
1
9223372036854775794
9223372036854775796
9223372036854775798
9223372036854775800
9223372036854775802
9223372036854775804
9223372036854775806
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551603);
SELECT * FROM t1;
c1
1
18446744073709551603
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 2
auto_increment_offset 10
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
SELECT * FROM t1;
c1
1
18446744073709551603
18446744073709551604
18446744073709551606
18446744073709551608
18446744073709551610
18446744073709551612
18446744073709551614
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551603);
SELECT * FROM t1;
c1
1
18446744073709551603
SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 5
auto_increment_offset 7
INSERT INTO t1 VALUES (NULL),(NULL);
SELECT * FROM t1;
c1
1
18446744073709551603
18446744073709551607
18446744073709551612
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES(-9223372036854775806);
INSERT INTO t1 VALUES(-9223372036854775807);
INSERT INTO t1 VALUES(-9223372036854775808);
SELECT * FROM t1;
c1
-9223372036854775808
-9223372036854775807
-9223372036854775806
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=3, @@SESSION.AUTO_INCREMENT_OFFSET=3;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 3
auto_increment_offset 3
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
SELECT * FROM t1;
c1
-9223372036854775808
-9223372036854775807
-9223372036854775806
1
3
6
9
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551610);
SELECT * FROM t1;
c1
1
18446744073709551610
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
Warnings:
Warning 1292 Truncated incorrect auto_increment_increment value: '1152921504606846976'
Warning 1292 Truncated incorrect auto_increment_offset value: '1152921504606846976'
SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 65535
auto_increment_offset 65535
INSERT INTO t1 VALUES (NULL);
SELECT * FROM t1;
c1
1
18446744073709551610
18446744073709551615
DROP TABLE t1;
...@@ -3295,3 +3295,11 @@ info: Records: 5 Duplicates: 0 Warnings: 0 ...@@ -3295,3 +3295,11 @@ info: Records: 5 Duplicates: 0 Warnings: 0
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
affected rows: 0 affected rows: 0
DROP TABLE t1; DROP TABLE t1;
Variable_name Value
Handler_update 0
Variable_name Value
Handler_delete 0
Variable_name Value
Handler_update 1
Variable_name Value
Handler_delete 1
SET storage_engine=InnoDB;
INSERT INTO bug38231 VALUES (1), (10), (300);
SET autocommit=0;
SELECT * FROM bug38231 FOR UPDATE;
a
1
10
300
TRUNCATE TABLE bug38231;
COMMIT;
DROP TABLE bug38231;
SET storage_engine=InnoDB;
...@@ -115,14 +115,14 @@ master-bin.000001 # Xid # # COMMIT /* XID */ ...@@ -115,14 +115,14 @@ master-bin.000001 # Xid # # COMMIT /* XID */
DROP TABLE t1; DROP TABLE t1;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
Variable_name Value Variable_name Value
Binlog_cache_use 15 Binlog_cache_use 13
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
Variable_name Value Variable_name Value
Binlog_cache_disk_use 0 Binlog_cache_disk_use 0
create table t1 (a int) engine=innodb; create table t1 (a int) engine=innodb;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
Variable_name Value Variable_name Value
Binlog_cache_use 16 Binlog_cache_use 14
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
Variable_name Value Variable_name Value
Binlog_cache_disk_use 1 Binlog_cache_disk_use 1
...@@ -131,7 +131,7 @@ delete from t1; ...@@ -131,7 +131,7 @@ delete from t1;
commit; commit;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
Variable_name Value Variable_name Value
Binlog_cache_use 17 Binlog_cache_use 15
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
Variable_name Value Variable_name Value
Binlog_cache_disk_use 1 Binlog_cache_disk_use 1
......
...@@ -139,3 +139,262 @@ SELECT c1 FROM t1; ...@@ -139,3 +139,262 @@ SELECT c1 FROM t1;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug 38839
# Reset the last value generated at end of statement
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, 1);
DELETE FROM t1 WHERE c1 = 1;
INSERT INTO t1 VALUES (2,1);
INSERT INTO t1 VALUES (NULL,8);
SELECT * FROM t1;
DROP TABLE t1;
# Bug 38839 -- same as above but for multi value insert
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, 1);
DELETE FROM t1 WHERE c1 = 1;
INSERT INTO t1 VALUES (2,1), (NULL, 8);
INSERT INTO t1 VALUES (NULL,9);
SELECT * FROM t1;
DROP TABLE t1;
#
# Test changes to AUTOINC next value calculation
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL),(5),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
INSERT INTO t1 VALUES (1000);
SET @@INSERT_ID=400;
INSERT INTO t1 VALUES(NULL),(NULL);
SELECT * FROM t1;
DROP TABLE t1;
# Test with SIGNED INT column, by inserting a 0 for the first column value
# 0 is treated in the same was NULL.
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(0);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
INSERT INTO t1 VALUES (-1), (NULL),(2),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
SET @@INSERT_ID=400;
# Duplicate error expected here for autoinc_lock_mode != TRADITIONAL
-- error ER_DUP_ENTRY,1062
INSERT INTO t1 VALUES(NULL),(NULL);
SELECT * FROM t1;
DROP TABLE t1;
# Test with SIGNED INT column
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
INSERT INTO t1 VALUES (-2), (NULL),(2),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
INSERT INTO t1 VALUES (1000);
SET @@INSERT_ID=400;
INSERT INTO t1 VALUES(NULL),(NULL);
SELECT * FROM t1;
DROP TABLE t1;
# Test with UNSIGNED INT column, single insert
# The sign in the value is ignored and a new column value is generated
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
INSERT INTO t1 VALUES (-2);
INSERT INTO t1 VALUES (NULL);
INSERT INTO t1 VALUES (2);
INSERT INTO t1 VALUES (NULL);
INSERT INTO t1 VALUES (250);
INSERT INTO t1 VALUES (NULL);
SELECT * FROM t1;
INSERT INTO t1 VALUES (1000);
SET @@INSERT_ID=400;
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES(NULL);
SELECT * FROM t1;
DROP TABLE t1;
# Test with UNSIGNED INT column, multi-value inserts
# The sign in the value is ignored and a new column value is generated
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
INSERT INTO t1 VALUES (-2),(NULL),(2),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
INSERT INTO t1 VALUES (1000);
SET @@INSERT_ID=400;
# Duplicate error expected here for autoinc_lock_mode != TRADITIONAL
-- error ER_DUP_ENTRY,1062
INSERT INTO t1 VALUES(NULL),(NULL);
SELECT * FROM t1;
DROP TABLE t1;
#
# Check for overflow handling when increment is > 1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
# We have to do this because of a bug in the AUTOINC init code.
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (9223372036854775794); -- 2^63 - 14
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
# This should just fit
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
SELECT * FROM t1;
DROP TABLE t1;
#
# Check for overflow handling when increment and offser are > 1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
# We have to do this because of a bug in the AUTOINC init code.
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551603); -- 2^64 - 13
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
SHOW VARIABLES LIKE "%auto_inc%";
# This should fail because of overflow but it doesn't, it seems to be
# a MySQL server bug. It wraps around to 0 for the last value.
# See MySQL Bug# 39828
#
# Instead of wrapping around, it asserts when MySQL is compiled --with-debug
# (see sql/handler.cc:handler::update_auto_increment()). Don't test for
# overflow until Bug #39828 is fixed.
#
# Since this asserts when compiled --with-debug, we can't properly test this
# until Bug #39828 is fixed. For now, this test is meaningless.
#if Bug #39828 is fixed
#INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
#else
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
#endif
SELECT * FROM t1;
DROP TABLE t1;
#
# Check for overflow handling when increment and offset are odd numbers
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
# We have to do this because of a bug in the AUTOINC init code.
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551603); -- 2^64 - 13
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
SHOW VARIABLES LIKE "%auto_inc%";
# This should fail because of overflow but it doesn't. It fails with
# a duplicate entry message because of a MySQL server bug, it wraps
# around. See MySQL Bug# 39828, once MySQL fix the bug we can replace
# the ER_DUP_ENTRY, 1062 below with the appropriate error message
#
# Since this asserts when compiled --with-debug, we can't properly test this
# until Bug #39828 is fixed. For now, this test is meaningless.
#if Bug #39828 is fixed
# Still need to fix this error code, error should mention overflow
#-- error ER_DUP_ENTRY,1062
#INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
#else
INSERT INTO t1 VALUES (NULL),(NULL);
#endif
SELECT * FROM t1;
DROP TABLE t1;
# Check for overflow handling when increment and offset are odd numbers
# and check for large -ve numbers
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
# We have to do this because of a bug in the AUTOINC init code.
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES(-9223372036854775806); -- -2^63 + 2
INSERT INTO t1 VALUES(-9223372036854775807); -- -2^63 + 1
INSERT INTO t1 VALUES(-9223372036854775808); -- -2^63
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=3, @@SESSION.AUTO_INCREMENT_OFFSET=3;
SHOW VARIABLES LIKE "%auto_inc%";
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
SELECT * FROM t1;
DROP TABLE t1;
#
# Check for overflow handling when increment and offset are very
# large numbers 2^60
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
# We have to do this because of a bug in the AUTOINC init code.
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551610); -- 2^64 - 2
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
SHOW VARIABLES LIKE "%auto_inc%";
# This should fail because of overflow but it doesn't. It wraps around
# and the autoinc values look bogus too.
# See MySQL Bug# 39828, once MySQL fix the bug we can enable the error
# code expected test.
# -- error ER_AUTOINC_READ_FAILED,1467
#
# Since this asserts when compiled --with-debug, we can't properly test this
# until Bug #39828 is fixed. For now, this test is meaningless.
#if Bug #39828 is fixed
#-- error ER_AUTOINC_READ_FAILED,1467
#INSERT INTO t1 VALUES (NULL),(NULL);
#else
INSERT INTO t1 VALUES (NULL);
#endif
SELECT * FROM t1;
DROP TABLE t1;
...@@ -2475,6 +2475,7 @@ SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2'; ...@@ -2475,6 +2475,7 @@ SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
# End 34920 test # End 34920 test
#
# Bug #29507 TRUNCATE shows to many rows effected # Bug #29507 TRUNCATE shows to many rows effected
# #
CONNECTION default; CONNECTION default;
...@@ -2491,6 +2492,36 @@ TRUNCATE TABLE t1; ...@@ -2491,6 +2492,36 @@ TRUNCATE TABLE t1;
--disable_info --disable_info
DROP TABLE t1; DROP TABLE t1;
# #
# Bug#35537 Innodb doesn't increment handler_update and handler_delete.
#
-- disable_query_log
-- disable_result_log
CONNECT (c1,localhost,root,,);
DROP TABLE IF EXISTS bug35537;
CREATE TABLE bug35537 (
c1 int
) ENGINE=InnoDB;
INSERT INTO bug35537 VALUES (1);
-- enable_result_log
SHOW SESSION STATUS LIKE 'Handler_update%';
SHOW SESSION STATUS LIKE 'Handler_delete%';
UPDATE bug35537 SET c1 = 2 WHERE c1 = 1;
DELETE FROM bug35537 WHERE c1 = 2;
SHOW SESSION STATUS LIKE 'Handler_update%';
SHOW SESSION STATUS LIKE 'Handler_delete%';
DROP TABLE bug35537;
DISCONNECT c1;
CONNECTION default;
####################################################################### #######################################################################
# # # #
# Please, DO NOT TOUCH this file as well as the innodb.result file. # # Please, DO NOT TOUCH this file as well as the innodb.result file. #
......
#
# Bug#38231 Innodb crash in lock_reset_all_on_table() on TRUNCATE + LOCK / UNLOCK
# http://bugs.mysql.com/38231
#
-- source include/have_innodb.inc
SET storage_engine=InnoDB;
# we care only that the following SQL commands do not crash the server
-- disable_query_log
-- disable_result_log
DROP TABLE IF EXISTS bug38231;
CREATE TABLE bug38231 (a INT);
-- connect (con1,localhost,root,,)
-- connect (con2,localhost,root,,)
-- connect (con3,localhost,root,,)
-- connection con1
SET autocommit=0;
LOCK TABLE bug38231 WRITE;
-- connection con2
SET autocommit=0;
-- send
LOCK TABLE bug38231 WRITE;
-- connection con3
SET autocommit=0;
-- send
LOCK TABLE bug38231 WRITE;
-- connection default
-- send
TRUNCATE TABLE bug38231;
-- connection con1
# give time to TRUNCATE and others to be executed; without sleep, sometimes
# UNLOCK executes before TRUNCATE
-- sleep 0.2
# this crashes the server if the bug is present
UNLOCK TABLES;
# clean up
-- connection con2
UNLOCK TABLES;
-- connection con3
UNLOCK TABLES;
-- connection default
-- disconnect con1
-- disconnect con2
-- disconnect con3
# test that TRUNCATE works with with row-level locks
-- enable_query_log
-- enable_result_log
INSERT INTO bug38231 VALUES (1), (10), (300);
-- connect (con4,localhost,root,,)
-- connection con4
SET autocommit=0;
SELECT * FROM bug38231 FOR UPDATE;
-- connection default
TRUNCATE TABLE bug38231;
-- connection con4
COMMIT;
-- connection default
-- disconnect con4
DROP TABLE bug38231;
#
# Bug#39438 Testcase for Bug#39436 crashes on 5.1 in fil_space_get_latch
# http://bugs.mysql.com/39438
#
# This test must be run with innodb_file_per_table=1 because the crash
# only occurs if that option is turned on and DISCARD TABLESPACE only
# works with innodb_file_per_table.
#
-- source include/have_innodb.inc
SET storage_engine=InnoDB;
# we care only that the following SQL commands do not crash the server
-- disable_query_log
-- disable_result_log
DROP TABLE IF EXISTS bug39438;
CREATE TABLE bug39438 (id INT) ENGINE=INNODB;
ALTER TABLE bug39438 DISCARD TABLESPACE;
# this crashes the server if the bug is present
SHOW TABLE STATUS;
DROP TABLE bug39438;
...@@ -15,21 +15,21 @@ ...@@ -15,21 +15,21 @@
# Process this file with automake to create Makefile.in # Process this file with automake to create Makefile.in
MYSQLDATAdir = $(localstatedir) MYSQLDATAdir= $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir) MYSQLSHAREdir= $(pkgdatadir)
MYSQLBASEdir= $(prefix) MYSQLBASEdir= $(prefix)
MYSQLLIBdir= $(pkglibdir) MYSQLLIBdir= $(pkglibdir)
pkgplugindir = $(pkglibdir)/plugin pkgplugindir= $(pkglibdir)/plugin
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
-I$(top_srcdir)/regex \ -I$(top_srcdir)/regex \
-I$(top_srcdir)/storage/innobase/include \ -I$(top_srcdir)/storage/innobase/include \
-I$(top_srcdir)/sql \ -I$(top_srcdir)/sql \
-I$(srcdir) -I$(srcdir)
DEFS = @DEFS@ DEFS= @DEFS@
noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \ noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \
include/btr0cur.h include/btr0cur.ic \ include/btr0cur.h include/btr0cur.ic \
include/btr0pcur.h include/btr0pcur.ic \ include/btr0pcur.h include/btr0pcur.ic \
include/btr0sea.h include/btr0sea.ic \ include/btr0sea.h include/btr0sea.ic \
...@@ -121,9 +121,9 @@ noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \ ...@@ -121,9 +121,9 @@ noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \
include/ut0list.ic include/ut0wqueue.h \ include/ut0list.ic include/ut0wqueue.h \
include/ha_prototypes.h handler/ha_innodb.h include/ha_prototypes.h handler/ha_innodb.h
EXTRA_LIBRARIES = libinnobase.a EXTRA_LIBRARIES= libinnobase.a
noinst_LIBRARIES = @plugin_innobase_static_target@ noinst_LIBRARIES= @plugin_innobase_static_target@
libinnobase_a_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \ libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c \ btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c \
buf/buf0lru.c buf/buf0rea.c data/data0data.c \ buf/buf0lru.c buf/buf0rea.c data/data0data.c \
data/data0type.c dict/dict0boot.c \ data/data0type.c dict/dict0boot.c \
...@@ -156,17 +156,17 @@ libinnobase_a_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \ ...@@ -156,17 +156,17 @@ libinnobase_a_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
handler/ha_innodb.cc handler/ha_innodb.cc
libinnobase_a_CXXFLAGS= $(AM_CFLAGS) libinnobase_a_CXXFLAGS= $(AM_CFLAGS)
libinnobase_a_CFLAGS = $(AM_CFLAGS) libinnobase_a_CFLAGS= $(AM_CFLAGS)
EXTRA_LTLIBRARIES = ha_innodb.la EXTRA_LTLIBRARIES= ha_innodb.la
pkgplugin_LTLIBRARIES= @plugin_innobase_shared_target@ pkgplugin_LTLIBRARIES= @plugin_innobase_shared_target@
ha_innodb_la_LDFLAGS = -module -rpath $(pkgplugindir) ha_innodb_la_LDFLAGS= -module -rpath $(pkgplugindir)
ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
ha_innodb_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_innodb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
ha_innodb_la_SOURCES = $(libinnobase_a_SOURCES) ha_innodb_la_SOURCES= $(libinnobase_a_SOURCES)
EXTRA_DIST = CMakeLists.txt plug.in \ EXTRA_DIST= CMakeLists.txt plug.in \
pars/make_bison.sh pars/make_flex.sh \ pars/make_bison.sh pars/make_flex.sh \
pars/pars0grm.y pars/pars0lex.l pars/pars0grm.y pars/pars0lex.l
......
...@@ -161,6 +161,7 @@ btr_search_info_create( ...@@ -161,6 +161,7 @@ btr_search_info_create(
info->magic_n = BTR_SEARCH_MAGIC_N; info->magic_n = BTR_SEARCH_MAGIC_N;
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
info->ref_count = 0;
info->root_guess = NULL; info->root_guess = NULL;
info->hash_analysis = 0; info->hash_analysis = 0;
...@@ -184,6 +185,31 @@ btr_search_info_create( ...@@ -184,6 +185,31 @@ btr_search_info_create(
return(info); return(info);
} }
/*********************************************************************
Returns the value of ref_count. The value is protected by
btr_search_latch. */
ulint
btr_search_info_get_ref_count(
/*==========================*/
/* out: ref_count value. */
btr_search_t* info) /* in: search info. */
{
ulint ret;
ut_ad(info);
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
rw_lock_s_lock(&btr_search_latch);
ret = info->ref_count;
rw_lock_s_unlock(&btr_search_latch);
return(ret);
}
/************************************************************************* /*************************************************************************
Updates the search info of an index about hash successes. NOTE that info Updates the search info of an index about hash successes. NOTE that info
is NOT protected by any semaphore, to save CPU time! Do not assume its fields is NOT protected by any semaphore, to save CPU time! Do not assume its fields
...@@ -1022,8 +1048,12 @@ btr_search_drop_page_hash_index( ...@@ -1022,8 +1048,12 @@ btr_search_drop_page_hash_index(
ha_remove_all_nodes_to_page(table, folds[i], page); ha_remove_all_nodes_to_page(table, folds[i], page);
} }
ut_a(index->search_info->ref_count > 0);
index->search_info->ref_count--;
block->is_hashed = FALSE; block->is_hashed = FALSE;
block->index = NULL; block->index = NULL;
cleanup: cleanup:
if (UNIV_UNLIKELY(block->n_pointers)) { if (UNIV_UNLIKELY(block->n_pointers)) {
/* Corruption */ /* Corruption */
...@@ -1244,6 +1274,15 @@ btr_search_build_page_hash_index( ...@@ -1244,6 +1274,15 @@ btr_search_build_page_hash_index(
goto exit_func; goto exit_func;
} }
/* This counter is decremented every time we drop page
hash index entries and is incremented here. Since we can
rebuild hash index for a page that is already hashed, we
have to take care not to increment the counter in that
case. */
if (!block->is_hashed) {
index->search_info->ref_count++;
}
block->is_hashed = TRUE; block->is_hashed = TRUE;
block->n_hash_helps = 0; block->n_hash_helps = 0;
......
...@@ -42,6 +42,11 @@ initial segment in buf_LRU_get_recent_limit */ ...@@ -42,6 +42,11 @@ initial segment in buf_LRU_get_recent_limit */
#define BUF_LRU_INITIAL_RATIO 8 #define BUF_LRU_INITIAL_RATIO 8
/* When dropping the search hash index entries before deleting an ibd
file, we build a local array of pages belonging to that tablespace
in the buffer pool. Following is the size of that array. */
#define BUF_LRU_DROP_SEARCH_HASH_SIZE 1024
/* If we switch on the InnoDB monitor because there are too few available /* If we switch on the InnoDB monitor because there are too few available
frames in the buffer pool, we set this to TRUE */ frames in the buffer pool, we set this to TRUE */
ibool buf_lru_switched_on_innodb_mon = FALSE; ibool buf_lru_switched_on_innodb_mon = FALSE;
...@@ -65,6 +70,120 @@ buf_LRU_block_free_hashed_page( ...@@ -65,6 +70,120 @@ buf_LRU_block_free_hashed_page(
buf_block_t* block); /* in: block, must contain a file page and buf_block_t* block); /* in: block, must contain a file page and
be in a state where it can be freed */ be in a state where it can be freed */
/**********************************************************************
Attempts to drop page hash index on a batch of pages belonging to a
particular space id. */
static
void
buf_LRU_drop_page_hash_batch(
/*=========================*/
ulint id, /* in: space id */
const ulint* arr, /* in: array of page_no */
ulint count) /* in: number of entries in array */
{
ulint i;
ut_ad(arr != NULL);
ut_ad(count <= BUF_LRU_DROP_SEARCH_HASH_SIZE);
for (i = 0; i < count; ++i) {
btr_search_drop_page_hash_when_freed(id, arr[i]);
}
}
/**********************************************************************
When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page
hash index entries belonging to that table. This function tries to
do that in batch. Note that this is a 'best effort' attempt and does
not guarantee that ALL hash entries will be removed. */
static
void
buf_LRU_drop_page_hash_for_tablespace(
/*==================================*/
ulint id) /* in: space id */
{
buf_block_t* block;
ulint* page_arr;
ulint num_entries;
page_arr = ut_malloc(sizeof(ulint)
* BUF_LRU_DROP_SEARCH_HASH_SIZE);
mutex_enter(&buf_pool->mutex);
scan_again:
num_entries = 0;
block = UT_LIST_GET_LAST(buf_pool->LRU);
while (block != NULL) {
buf_block_t* prev_block;
mutex_enter(&block->mutex);
prev_block = UT_LIST_GET_PREV(LRU, block);
ut_a(block->state == BUF_BLOCK_FILE_PAGE);
if (block->space != id
|| block->buf_fix_count > 0
|| block->io_fix != 0) {
/* We leave the fixed pages as is in this scan.
To be dealt with later in the final scan. */
mutex_exit(&block->mutex);
goto next_page;
}
ut_ad(block->space == id);
if (block->is_hashed) {
/* Store the offset(i.e.: page_no) in the array
so that we can drop hash index in a batch
later. */
page_arr[num_entries] = block->offset;
mutex_exit(&block->mutex);
ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
++num_entries;
if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
goto next_page;
}
/* Array full. We release the buf_pool->mutex to
obey the latching order. */
mutex_exit(&buf_pool->mutex);
buf_LRU_drop_page_hash_batch(id, page_arr,
num_entries);
num_entries = 0;
mutex_enter(&buf_pool->mutex);
} else {
mutex_exit(&block->mutex);
}
next_page:
/* Note that we may have released the buf_pool->mutex
above after reading the prev_block during processing
of a page_hash_batch (i.e.: when the array was full).
This means that prev_block can change in LRU list.
This is OK because this function is a 'best effort'
to drop as many search hash entries as possible and
it does not guarantee that ALL such entries will be
dropped. */
block = prev_block;
/* If, however, block has been removed from LRU list
to the free list then we should restart the scan.
block->state is protected by buf_pool->mutex. */
if (block && block->state != BUF_BLOCK_FILE_PAGE) {
ut_a(num_entries == 0);
goto scan_again;
}
}
mutex_exit(&buf_pool->mutex);
/* Drop any remaining batch of search hashed pages. */
buf_LRU_drop_page_hash_batch(id, page_arr, num_entries);
ut_free(page_arr);
}
/********************************************************************** /**********************************************************************
Invalidates all pages belonging to a given tablespace when we are deleting Invalidates all pages belonging to a given tablespace when we are deleting
the data file(s) of that tablespace. */ the data file(s) of that tablespace. */
...@@ -78,6 +197,14 @@ buf_LRU_invalidate_tablespace( ...@@ -78,6 +197,14 @@ buf_LRU_invalidate_tablespace(
ulint page_no; ulint page_no;
ibool all_freed; ibool all_freed;
/* Before we attempt to drop pages one by one we first
attempt to drop page hash index entries in batches to make
it more efficient. The batching attempt is a best effort
attempt and does not guarantee that all pages hash entries
will be dropped. We get rid of remaining page hash entries
one by one below. */
buf_LRU_drop_page_hash_for_tablespace(id);
scan_again: scan_again:
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
......
...@@ -422,8 +422,7 @@ dict_table_autoinc_lock( ...@@ -422,8 +422,7 @@ dict_table_autoinc_lock(
} }
/************************************************************************ /************************************************************************
Initializes the autoinc counter. It is not an error to initialize an already Unconditionally set the autoinc counter. */
initialized counter. */
void void
dict_table_autoinc_initialize( dict_table_autoinc_initialize(
...@@ -433,7 +432,6 @@ dict_table_autoinc_initialize( ...@@ -433,7 +432,6 @@ dict_table_autoinc_initialize(
{ {
ut_ad(mutex_own(&table->autoinc_mutex)); ut_ad(mutex_own(&table->autoinc_mutex));
table->autoinc_inited = TRUE;
table->autoinc = value; table->autoinc = value;
} }
...@@ -447,32 +445,25 @@ dict_table_autoinc_read( ...@@ -447,32 +445,25 @@ dict_table_autoinc_read(
/* out: value for a new row, or 0 */ /* out: value for a new row, or 0 */
dict_table_t* table) /* in: table */ dict_table_t* table) /* in: table */
{ {
ib_longlong value;
ut_ad(mutex_own(&table->autoinc_mutex)); ut_ad(mutex_own(&table->autoinc_mutex));
if (!table->autoinc_inited) { return(table->autoinc);
value = 0;
} else {
value = table->autoinc;
}
return(value);
} }
/************************************************************************ /************************************************************************
Updates the autoinc counter if the value supplied is greater than the Updates the autoinc counter if the value supplied is greater than the
current value. If not inited, does nothing. */ current value. */
void void
dict_table_autoinc_update( dict_table_autoinc_update_if_greater(
/*======================*/ /*=================================*/
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
ib_ulonglong value) /* in: value which was assigned to a row */ ib_ulonglong value) /* in: value which was assigned to a row */
{ {
if (table->autoinc_inited && value > table->autoinc) { ut_ad(mutex_own(&table->autoinc_mutex));
if (value > table->autoinc) {
table->autoinc = value; table->autoinc = value;
} }
...@@ -1394,12 +1385,59 @@ dict_index_remove_from_cache( ...@@ -1394,12 +1385,59 @@ dict_index_remove_from_cache(
dict_index_t* index) /* in, own: index */ dict_index_t* index) /* in, own: index */
{ {
ulint size; ulint size;
ulint retries = 0;
btr_search_t* info;
ut_ad(table && index); ut_ad(table && index);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
/* We always create search info whether or not adaptive
hash index is enabled or not. */
info = index->search_info;
ut_ad(info);
/* We are not allowed to free the in-memory index struct
dict_index_t until all entries in the adaptive hash index
that point to any of the page belonging to his b-tree index
are dropped. This is so because dropping of these entries
require access to dict_index_t struct. To avoid such scenario
We keep a count of number of such pages in the search_info and
only free the dict_index_t struct when this count drops to
zero. */
for (;;) {
ulint ref_count = btr_search_info_get_ref_count(info);
if (ref_count == 0) {
break;
}
/* Sleep for 10ms before trying again. */
os_thread_sleep(10000);
++retries;
if (retries % 500 == 0) {
/* No luck after 5 seconds of wait. */
fprintf(stderr, "InnoDB: Error: Waited for"
" %lu secs for hash index"
" ref_count (%lu) to drop"
" to 0.\n"
"index: \"%s\""
" table: \"%s\"\n",
retries/100,
ref_count,
index->name,
table->name);
}
/* To avoid a hang here we commit suicide if the
ref_count doesn't drop to zero in 600 seconds. */
if (retries >= 60000) {
ut_error;
}
}
rw_lock_free(&index->lock); rw_lock_free(&index->lock);
/* Remove the index from the list of indexes of the table */ /* Remove the index from the list of indexes of the table */
......
...@@ -89,11 +89,7 @@ dict_mem_table_create( ...@@ -89,11 +89,7 @@ dict_mem_table_create(
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX); mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
table->autoinc_inited = FALSE; table->autoinc = 0;
/* The actual increment value will be set by MySQL, we simply
default to 1 here.*/
table->autoinc_increment = 1;
/* The number of transactions that are either waiting on the /* The number of transactions that are either waiting on the
AUTOINC lock or have been granted the lock. */ AUTOINC lock or have been granted the lock. */
......
This diff is collapsed.
...@@ -72,12 +72,15 @@ class ha_innobase: public handler ...@@ -72,12 +72,15 @@ class ha_innobase: public handler
int update_thd(THD* thd); int update_thd(THD* thd);
int change_active_index(uint keynr); int change_active_index(uint keynr);
int general_fetch(uchar* buf, uint direction, uint match_mode); int general_fetch(uchar* buf, uint direction, uint match_mode);
int innobase_read_and_init_auto_inc(ulonglong* ret); ulong innobase_lock_autoinc();
ulong innobase_autoinc_lock(); ulonglong innobase_peek_autoinc();
ulong innobase_set_max_autoinc(ulonglong auto_inc); ulong innobase_set_max_autoinc(ulonglong auto_inc);
ulong innobase_reset_autoinc(ulonglong auto_inc); ulong innobase_reset_autoinc(ulonglong auto_inc);
ulong innobase_get_auto_increment(ulonglong* value); ulong innobase_get_autoinc(ulonglong* value);
ulong innobase_update_autoinc(ulonglong auto_inc);
ulong innobase_initialize_autoinc();
dict_index_t* innobase_get_index(uint keynr); dict_index_t* innobase_get_index(uint keynr);
ulonglong innobase_get_int_col_max_value(const Field* field);
/* Init values for the class: */ /* Init values for the class: */
public: public:
......
...@@ -40,6 +40,14 @@ btr_search_info_create( ...@@ -40,6 +40,14 @@ btr_search_info_create(
/*===================*/ /*===================*/
/* out, own: search info struct */ /* out, own: search info struct */
mem_heap_t* heap); /* in: heap where created */ mem_heap_t* heap); /* in: heap where created */
/*********************************************************************
Returns the value of ref_count. The value is protected by
btr_search_latch. */
ulint
btr_search_info_get_ref_count(
/*==========================*/
/* out: ref_count value. */
btr_search_t* info); /* in: search info. */
/************************************************************************* /*************************************************************************
Updates the search info. */ Updates the search info. */
UNIV_INLINE UNIV_INLINE
...@@ -137,6 +145,13 @@ btr_search_validate(void); ...@@ -137,6 +145,13 @@ btr_search_validate(void);
/* The search info struct in an index */ /* The search info struct in an index */
struct btr_search_struct{ struct btr_search_struct{
ulint ref_count; /* Number of blocks in this index tree
that have search index built
i.e. block->index points to this index.
Protected by btr_search_latch except
when during initialization in
btr_search_info_create(). */
/* The following fields are not protected by any latch. /* The following fields are not protected by any latch.
Unfortunately, this means that they must be aligned to Unfortunately, this means that they must be aligned to
the machine word, i.e., they cannot be turned into bit-fields. */ the machine word, i.e., they cannot be turned into bit-fields. */
......
...@@ -178,8 +178,7 @@ dict_table_autoinc_lock( ...@@ -178,8 +178,7 @@ dict_table_autoinc_lock(
/*====================*/ /*====================*/
dict_table_t* table); /* in: table */ dict_table_t* table); /* in: table */
/************************************************************************ /************************************************************************
Initializes the autoinc counter. It is not an error to initialize an already Unconditionally set the autoinc counter. */
initialized counter. */
void void
dict_table_autoinc_initialize( dict_table_autoinc_initialize(
...@@ -196,12 +195,12 @@ dict_table_autoinc_read( ...@@ -196,12 +195,12 @@ dict_table_autoinc_read(
/* out: value for a new row, or 0 */ /* out: value for a new row, or 0 */
dict_table_t* table); /* in: table */ dict_table_t* table); /* in: table */
/************************************************************************ /************************************************************************
Updates the autoinc counter if the value supplied is equal or bigger than the Updates the autoinc counter if the value supplied is greater than the
current value. If not inited, does nothing. */ current value. */
void void
dict_table_autoinc_update( dict_table_autoinc_update_if_greater(
/*======================*/ /*=================================*/
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
ib_ulonglong value); /* in: value which was assigned to a row */ ib_ulonglong value); /* in: value which was assigned to a row */
......
...@@ -405,17 +405,8 @@ struct dict_table_struct{ ...@@ -405,17 +405,8 @@ struct dict_table_struct{
mutex_t autoinc_mutex; mutex_t autoinc_mutex;
/* mutex protecting the autoincrement /* mutex protecting the autoincrement
counter */ counter */
ibool autoinc_inited;
/* TRUE if the autoinc counter has been
inited; MySQL gets the init value by executing
SELECT MAX(auto inc column) */
ib_ulonglong autoinc;/* autoinc counter value to give to the ib_ulonglong autoinc;/* autoinc counter value to give to the
next inserted row */ next inserted row */
ib_longlong autoinc_increment;
/* The increment step of the auto increment
column. Value must be greater than or equal
to 1 */
ulong n_waiting_or_granted_auto_inc_locks; ulong n_waiting_or_granted_auto_inc_locks;
/* This counter is used to track the number /* This counter is used to track the number
of granted and pending autoinc locks on this of granted and pending autoinc locks on this
...@@ -425,6 +416,7 @@ struct dict_table_struct{ ...@@ -425,6 +416,7 @@ struct dict_table_struct{
acquired the AUTOINC lock or not. Of course acquired the AUTOINC lock or not. Of course
only one transaction can be granted the only one transaction can be granted the
lock but there can be multiple waiters. */ lock but there can be multiple waiters. */
/*----------------------*/
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
ulint magic_n;/* magic number */ ulint magic_n;/* magic number */
......
...@@ -63,5 +63,14 @@ thd_has_edited_nontrans_tables( ...@@ -63,5 +63,14 @@ thd_has_edited_nontrans_tables(
been edited */ been edited */
void* thd); /* in: thread handle (THD*) */ void* thd); /* in: thread handle (THD*) */
/**********************************************************************
Returns true if the thread is executing a SELECT statement. */
ibool
thd_is_select(
/*==========*/
/* out: true if thd is executing SELECT */
const void* thd); /* in: thread handle (THD*) */
#endif #endif
#endif #endif
...@@ -463,14 +463,21 @@ void ...@@ -463,14 +463,21 @@ void
lock_cancel_waiting_and_release( lock_cancel_waiting_and_release(
/*============================*/ /*============================*/
lock_t* lock); /* in: waiting lock request */ lock_t* lock); /* in: waiting lock request */
/************************************************************************* /*************************************************************************
Resets all locks, both table and record locks, on a table to be dropped. Removes locks on a table to be dropped or truncated.
No lock is allowed to be a wait lock. */ If remove_also_table_sx_locks is TRUE then table-level S and X locks are
also removed in addition to other table-level and record-level locks.
No lock, that is going to be removed, is allowed to be a wait lock. */
void void
lock_reset_all_on_table( lock_remove_all_on_table(
/*====================*/ /*=====================*/
dict_table_t* table); /* in: table to be dropped */ dict_table_t* table, /* in: table to be dropped
or truncated */
ibool remove_also_table_sx_locks);/* in: also removes
table S and X locks */
/************************************************************************* /*************************************************************************
Calculates the fold value of a page file address: used in inserting or Calculates the fold value of a page file address: used in inserting or
searching for a lock in the hash table. */ searching for a lock in the hash table. */
......
...@@ -683,7 +683,21 @@ struct row_prebuilt_struct { ...@@ -683,7 +683,21 @@ struct row_prebuilt_struct {
to this heap */ to this heap */
mem_heap_t* old_vers_heap; /* memory heap where a previous mem_heap_t* old_vers_heap; /* memory heap where a previous
version is built in consistent read */ version is built in consistent read */
ulonglong last_value; /* last value of AUTO-INC interval */ /*----------------------*/
ulonglong autoinc_last_value;/* last value of AUTO-INC interval */
ulonglong autoinc_increment;/* The increment step of the auto
increment column. Value must be
greater than or equal to 1. Required to
calculate the next value */
ulonglong autoinc_offset; /* The offset passed to
get_auto_increment() by MySQL. Required
to calculate the next value */
ulint autoinc_error; /* The actual error code encountered
while trying to init or read the
autoinc value from the table. We
store it here so that we can return
it to MySQL */
/*----------------------*/
ulint magic_n2; /* this should be the same as ulint magic_n2; /* this should be the same as
magic_n */ magic_n */
}; };
......
...@@ -197,7 +197,7 @@ mutex_exit( ...@@ -197,7 +197,7 @@ mutex_exit(
{ {
ut_ad(mutex_own(mutex)); ut_ad(mutex_own(mutex));
ut_d(mutex->thread_id = ULINT_UNDEFINED); ut_d(mutex->thread_id = (os_thread_id_t) ULINT_UNDEFINED);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
sync_thread_reset_level(mutex); sync_thread_reset_level(mutex);
......
...@@ -145,11 +145,15 @@ ib_time_t ...@@ -145,11 +145,15 @@ ib_time_t
ut_time(void); ut_time(void);
/*=========*/ /*=========*/
/************************************************************** /**************************************************************
Returns system time. */ Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
value -1 is returned and the global variable errno is set to indicate the
error. */
void int
ut_usectime( ut_usectime(
/*========*/ /*========*/
/* out: 0 on success, -1 otherwise */
ulint* sec, /* out: seconds since the Epoch */ ulint* sec, /* out: seconds since the Epoch */
ulint* ms); /* out: microseconds since the Epoch+*sec */ ulint* ms); /* out: microseconds since the Epoch+*sec */
/************************************************************** /**************************************************************
......
...@@ -3920,15 +3920,25 @@ lock_cancel_waiting_and_release( ...@@ -3920,15 +3920,25 @@ lock_cancel_waiting_and_release(
trx_end_lock_wait(lock->trx); trx_end_lock_wait(lock->trx);
} }
/* True if a lock mode is S or X */
#define IS_LOCK_S_OR_X(lock) \
(lock_get_mode(lock) == LOCK_S \
|| lock_get_mode(lock) == LOCK_X)
/************************************************************************* /*************************************************************************
Resets all record and table locks of a transaction on a table to be dropped. Removes locks of a transaction on a table to be dropped.
No lock is allowed to be a wait lock. */ If remove_also_table_sx_locks is TRUE then table-level S and X locks are
also removed in addition to other table-level and record-level locks.
No lock, that is going to be removed, is allowed to be a wait lock. */
static static
void void
lock_reset_all_on_table_for_trx( lock_remove_all_on_table_for_trx(
/*============================*/ /*=============================*/
dict_table_t* table, /* in: table to be dropped */ dict_table_t* table, /* in: table to be dropped */
trx_t* trx) /* in: a transaction */ trx_t* trx, /* in: a transaction */
ibool remove_also_table_sx_locks)/* in: also removes
table S and X locks */
{ {
lock_t* lock; lock_t* lock;
lock_t* prev_lock; lock_t* prev_lock;
...@@ -3946,7 +3956,9 @@ lock_reset_all_on_table_for_trx( ...@@ -3946,7 +3956,9 @@ lock_reset_all_on_table_for_trx(
lock_rec_discard(lock); lock_rec_discard(lock);
} else if (lock_get_type(lock) & LOCK_TABLE } else if (lock_get_type(lock) & LOCK_TABLE
&& lock->un_member.tab_lock.table == table) { && lock->un_member.tab_lock.table == table
&& (remove_also_table_sx_locks
|| !IS_LOCK_S_OR_X(lock))) {
ut_a(!lock_get_wait(lock)); ut_a(!lock_get_wait(lock));
...@@ -3958,27 +3970,66 @@ lock_reset_all_on_table_for_trx( ...@@ -3958,27 +3970,66 @@ lock_reset_all_on_table_for_trx(
} }
/************************************************************************* /*************************************************************************
Resets all locks, both table and record locks, on a table to be dropped. Removes locks on a table to be dropped or truncated.
No lock is allowed to be a wait lock. */ If remove_also_table_sx_locks is TRUE then table-level S and X locks are
also removed in addition to other table-level and record-level locks.
No lock, that is going to be removed, is allowed to be a wait lock. */
void void
lock_reset_all_on_table( lock_remove_all_on_table(
/*====================*/ /*=====================*/
dict_table_t* table) /* in: table to be dropped */ dict_table_t* table, /* in: table to be dropped
or truncated */
ibool remove_also_table_sx_locks)/* in: also removes
table S and X locks */
{ {
lock_t* lock; lock_t* lock;
lock_t* prev_lock;
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
lock = UT_LIST_GET_FIRST(table->locks); lock = UT_LIST_GET_FIRST(table->locks);
while (lock) { while (lock != NULL) {
prev_lock = UT_LIST_GET_PREV(un_member.tab_lock.locks,
lock);
/* If we should remove all locks (remove_also_table_sx_locks
is TRUE), or if the lock is not table-level S or X lock,
then check we are not going to remove a wait lock. */
if (remove_also_table_sx_locks
|| !(lock_get_type(lock) == LOCK_TABLE
&& IS_LOCK_S_OR_X(lock))) {
ut_a(!lock_get_wait(lock)); ut_a(!lock_get_wait(lock));
}
lock_reset_all_on_table_for_trx(table, lock->trx); lock_remove_all_on_table_for_trx(table, lock->trx,
remove_also_table_sx_locks);
if (prev_lock == NULL) {
if (lock == UT_LIST_GET_FIRST(table->locks)) {
/* lock was not removed, pick its successor */
lock = UT_LIST_GET_NEXT(
un_member.tab_lock.locks, lock);
} else {
/* lock was removed, pick the first one */
lock = UT_LIST_GET_FIRST(table->locks); lock = UT_LIST_GET_FIRST(table->locks);
} }
} else if (UT_LIST_GET_NEXT(un_member.tab_lock.locks,
prev_lock) != lock) {
/* If lock was removed by
lock_remove_all_on_table_for_trx() then pick the
successor of prev_lock ... */
lock = UT_LIST_GET_NEXT(
un_member.tab_lock.locks, prev_lock);
} else {
/* ... otherwise pick the successor of lock. */
lock = UT_LIST_GET_NEXT(
un_member.tab_lock.locks, lock);
}
}
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
} }
......
...@@ -1267,9 +1267,19 @@ os_file_create( ...@@ -1267,9 +1267,19 @@ os_file_create(
if (file == INVALID_HANDLE_VALUE) { if (file == INVALID_HANDLE_VALUE) {
*success = FALSE; *success = FALSE;
/* When srv_file_per_table is on, file creation failure may not
be critical to the whole instance. Do not crash the server in
case of unknown errors. */
if (srv_file_per_table) {
retry = os_file_handle_error_no_exit(name,
create_mode == OS_FILE_CREATE ?
"create" : "open");
} else {
retry = os_file_handle_error(name, retry = os_file_handle_error(name,
create_mode == OS_FILE_CREATE ? create_mode == OS_FILE_CREATE ?
"create" : "open"); "create" : "open");
}
if (retry) { if (retry) {
goto try_again; goto try_again;
} }
...@@ -1344,9 +1354,19 @@ os_file_create( ...@@ -1344,9 +1354,19 @@ os_file_create(
if (file == -1) { if (file == -1) {
*success = FALSE; *success = FALSE;
/* When srv_file_per_table is on, file creation failure may not
be critical to the whole instance. Do not crash the server in
case of unknown errors. */
if (srv_file_per_table) {
retry = os_file_handle_error_no_exit(name,
create_mode == OS_FILE_CREATE ?
"create" : "open");
} else {
retry = os_file_handle_error(name, retry = os_file_handle_error(name,
create_mode == OS_FILE_CREATE ? create_mode == OS_FILE_CREATE ?
"create" : "open"); "create" : "open");
}
if (retry) { if (retry) {
goto try_again; goto try_again;
} else { } else {
......
...@@ -23,17 +23,22 @@ MYSQL_PLUGIN_ACTIONS(innobase, [ ...@@ -23,17 +23,22 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE -DUNIV_HPUX";; CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE -DUNIV_HPUX";;
aix*) aix*)
CFLAGS="$CFLAGS -DUNIV_AIX";; CFLAGS="$CFLAGS -DUNIV_AIX";;
irix*) irix*|osf*|sysv5uw7*|openbsd*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
osf*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";; CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
*solaris*|*SunOS*) *solaris*|*SunOS*)
CFLAGS="$CFLAGS -DUNIV_SOLARIS";; CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
sysv5uw7*)
# Problem when linking on SCO
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
openbsd*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
esac esac
INNODB_DYNAMIC_CFLAGS="-DMYSQL_DYNAMIC_PLUGIN"
case "$target_cpu" in
x86_64)
# The AMD64 ABI forbids absolute addresses in shared libraries
;;
*86)
# Use absolute addresses on IA-32
INNODB_DYNAMIC_CFLAGS="$INNODB_DYNAMIC_CFLAGS -prefer-non-pic"
;;
esac
AC_SUBST(INNODB_DYNAMIC_CFLAGS)
]) ])
# vim: set ft=config:
...@@ -661,7 +661,14 @@ row_create_prebuilt( ...@@ -661,7 +661,14 @@ row_create_prebuilt(
prebuilt->old_vers_heap = NULL; prebuilt->old_vers_heap = NULL;
prebuilt->last_value = 0; prebuilt->autoinc_error = 0;
prebuilt->autoinc_offset = 0;
/* Default to 1, we will set the actual value later in
ha_innobase::get_auto_increment(). */
prebuilt->autoinc_increment = 1;
prebuilt->autoinc_last_value = 0;
return(prebuilt); return(prebuilt);
} }
...@@ -1963,6 +1970,7 @@ row_create_index_for_mysql( ...@@ -1963,6 +1970,7 @@ row_create_index_for_mysql(
ulint err; ulint err;
ulint i, j; ulint i, j;
ulint len; ulint len;
char* table_name;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
...@@ -1972,6 +1980,11 @@ row_create_index_for_mysql( ...@@ -1972,6 +1980,11 @@ row_create_index_for_mysql(
trx->op_info = "creating index"; trx->op_info = "creating index";
/* Copy the table name because we may want to drop the
table later, after the index object is freed (inside
que_run_threads()) and thus index->table_name is not available. */
table_name = mem_strdup(index->table_name);
trx_start_if_not_started(trx); trx_start_if_not_started(trx);
/* Check that the same column does not appear twice in the index. /* Check that the same column does not appear twice in the index.
...@@ -2044,13 +2057,15 @@ row_create_index_for_mysql( ...@@ -2044,13 +2057,15 @@ row_create_index_for_mysql(
trx_general_rollback_for_mysql(trx, FALSE, NULL); trx_general_rollback_for_mysql(trx, FALSE, NULL);
row_drop_table_for_mysql(index->table_name, trx, FALSE); row_drop_table_for_mysql(table_name, trx, FALSE);
trx->error_state = DB_SUCCESS; trx->error_state = DB_SUCCESS;
} }
trx->op_info = ""; trx->op_info = "";
mem_free(table_name);
return((int) err); return((int) err);
} }
...@@ -2443,8 +2458,8 @@ row_discard_tablespace_for_mysql( ...@@ -2443,8 +2458,8 @@ row_discard_tablespace_for_mysql(
new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
/* Remove any locks there are on the table or its records */ /* Remove all locks except the table-level S and X locks. */
lock_reset_all_on_table(table); lock_remove_all_on_table(table, FALSE);
info = pars_info_create(); info = pars_info_create();
...@@ -2779,9 +2794,8 @@ row_truncate_table_for_mysql( ...@@ -2779,9 +2794,8 @@ row_truncate_table_for_mysql(
goto funct_exit; goto funct_exit;
} }
/* Remove any locks there are on the table or its records */ /* Remove all locks except the table-level S and X locks. */
lock_remove_all_on_table(table, FALSE);
lock_reset_all_on_table(table);
trx->table_id = table->id; trx->table_id = table->id;
...@@ -2896,7 +2910,7 @@ row_truncate_table_for_mysql( ...@@ -2896,7 +2910,7 @@ row_truncate_table_for_mysql(
/* MySQL calls ha_innobase::reset_auto_increment() which does /* MySQL calls ha_innobase::reset_auto_increment() which does
the same thing. */ the same thing. */
dict_table_autoinc_lock(table); dict_table_autoinc_lock(table);
dict_table_autoinc_initialize(table, 0); dict_table_autoinc_initialize(table, 1);
dict_table_autoinc_unlock(table); dict_table_autoinc_unlock(table);
dict_update_statistics(table); dict_update_statistics(table);
...@@ -3131,9 +3145,8 @@ row_drop_table_for_mysql( ...@@ -3131,9 +3145,8 @@ row_drop_table_for_mysql(
goto funct_exit; goto funct_exit;
} }
/* Remove any locks there are on the table or its records */ /* Remove all locks there are on the table or its records */
lock_remove_all_on_table(table, TRUE);
lock_reset_all_on_table(table);
trx->dict_operation = TRUE; trx->dict_operation = TRUE;
trx->table_id = table->id; trx->table_id = table->id;
...@@ -3429,8 +3442,6 @@ row_drop_database_for_mysql( ...@@ -3429,8 +3442,6 @@ row_drop_database_for_mysql(
err = row_drop_table_for_mysql(table_name, trx, TRUE); err = row_drop_table_for_mysql(table_name, trx, TRUE);
mem_free(table_name);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
fputs("InnoDB: DROP DATABASE ", stderr); fputs("InnoDB: DROP DATABASE ", stderr);
ut_print_name(stderr, trx, TRUE, name); ut_print_name(stderr, trx, TRUE, name);
...@@ -3438,8 +3449,11 @@ row_drop_database_for_mysql( ...@@ -3438,8 +3449,11 @@ row_drop_database_for_mysql(
(ulint) err); (ulint) err);
ut_print_name(stderr, trx, TRUE, table_name); ut_print_name(stderr, trx, TRUE, table_name);
putc('\n', stderr); putc('\n', stderr);
mem_free(table_name);
break; break;
} }
mem_free(table_name);
} }
if (err == DB_SUCCESS) { if (err == DB_SUCCESS) {
......
...@@ -32,6 +32,7 @@ Created 12/19/1997 Heikki Tuuri ...@@ -32,6 +32,7 @@ Created 12/19/1997 Heikki Tuuri
#include "row0mysql.h" #include "row0mysql.h"
#include "read0read.h" #include "read0read.h"
#include "buf0lru.h" #include "buf0lru.h"
#include "ha_prototypes.h"
/* Maximum number of rows to prefetch; MySQL interface has another parameter */ /* Maximum number of rows to prefetch; MySQL interface has another parameter */
#define SEL_MAX_N_PREFETCH 16 #define SEL_MAX_N_PREFETCH 16
...@@ -3577,21 +3578,13 @@ row_search_for_mysql( ...@@ -3577,21 +3578,13 @@ row_search_for_mysql(
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
&& prebuilt->select_lock_type != LOCK_NONE && prebuilt->select_lock_type != LOCK_NONE
&& trx->mysql_query_str != NULL && trx->mysql_thd != NULL
&& *trx->mysql_query_str != NULL && thd_is_select(trx->mysql_thd)) {
&& trx->mysql_thd != NULL) {
/* Scan the MySQL query string; check if SELECT is the first
word there */
if (dict_str_starts_with_keyword(
trx->mysql_thd, *trx->mysql_query_str, "SELECT")) {
/* It is a plain locking SELECT and the isolation /* It is a plain locking SELECT and the isolation
level is low: do not lock gaps */ level is low: do not lock gaps */
set_also_gap_locks = FALSE; set_also_gap_locks = FALSE;
} }
}
/* Note that if the search mode was GE or G, then the cursor /* Note that if the search mode was GE or G, then the cursor
naturally moves upward (in fetch next) in alphabetical order, naturally moves upward (in fetch next) in alphabetical order,
......
...@@ -1453,9 +1453,12 @@ srv_suspend_mysql_thread( ...@@ -1453,9 +1453,12 @@ srv_suspend_mysql_thread(
srv_n_lock_wait_count++; srv_n_lock_wait_count++;
srv_n_lock_wait_current_count++; srv_n_lock_wait_current_count++;
ut_usectime(&sec, &ms); if (ut_usectime(&sec, &ms) == -1) {
start_time = -1;
} else {
start_time = (ib_longlong)sec * 1000000 + ms; start_time = (ib_longlong)sec * 1000000 + ms;
} }
}
/* Wake the lock timeout monitor thread, if it is suspended */ /* Wake the lock timeout monitor thread, if it is suspended */
os_event_set(srv_lock_timeout_thread_event); os_event_set(srv_lock_timeout_thread_event);
...@@ -1508,14 +1511,20 @@ srv_suspend_mysql_thread( ...@@ -1508,14 +1511,20 @@ srv_suspend_mysql_thread(
wait_time = ut_difftime(ut_time(), slot->suspend_time); wait_time = ut_difftime(ut_time(), slot->suspend_time);
if (thr->lock_state == QUE_THR_LOCK_ROW) { if (thr->lock_state == QUE_THR_LOCK_ROW) {
ut_usectime(&sec, &ms); if (ut_usectime(&sec, &ms) == -1) {
finish_time = -1;
} else {
finish_time = (ib_longlong)sec * 1000000 + ms; finish_time = (ib_longlong)sec * 1000000 + ms;
}
diff_time = (ulint) (finish_time - start_time); diff_time = (ulint) (finish_time - start_time);
srv_n_lock_wait_current_count--; srv_n_lock_wait_current_count--;
srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time; srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time;
if (diff_time > srv_n_lock_max_wait_time) { if (diff_time > srv_n_lock_max_wait_time &&
/* only update the variable if we successfully
retrieved the start and finish times. See Bug#36819. */
start_time != -1 && finish_time != -1) {
srv_n_lock_max_wait_time = diff_time; srv_n_lock_max_wait_time = diff_time;
} }
} }
......
...@@ -202,12 +202,12 @@ srv_parse_data_file_paths_and_sizes( ...@@ -202,12 +202,12 @@ srv_parse_data_file_paths_and_sizes(
str = srv_parse_megabytes(str, &size); str = srv_parse_megabytes(str, &size);
if (0 == memcmp(str, ":autoextend", if (0 == strncmp(str, ":autoextend",
(sizeof ":autoextend") - 1)) { (sizeof ":autoextend") - 1)) {
str += (sizeof ":autoextend") - 1; str += (sizeof ":autoextend") - 1;
if (0 == memcmp(str, ":max:", if (0 == strncmp(str, ":max:",
(sizeof ":max:") - 1)) { (sizeof ":max:") - 1)) {
str += (sizeof ":max:") - 1; str += (sizeof ":max:") - 1;
...@@ -290,14 +290,15 @@ srv_parse_data_file_paths_and_sizes( ...@@ -290,14 +290,15 @@ srv_parse_data_file_paths_and_sizes(
(*data_file_names)[i] = path; (*data_file_names)[i] = path;
(*data_file_sizes)[i] = size; (*data_file_sizes)[i] = size;
if (0 == memcmp(str, ":autoextend", if (0 == strncmp(str, ":autoextend",
(sizeof ":autoextend") - 1)) { (sizeof ":autoextend") - 1)) {
*is_auto_extending = TRUE; *is_auto_extending = TRUE;
str += (sizeof ":autoextend") - 1; str += (sizeof ":autoextend") - 1;
if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) { if (0 == strncmp(str, ":max:",
(sizeof ":max:") - 1)) {
str += (sizeof ":max:") - 1; str += (sizeof ":max:") - 1;
......
...@@ -112,19 +112,45 @@ ut_time(void) ...@@ -112,19 +112,45 @@ ut_time(void)
} }
/************************************************************** /**************************************************************
Returns system time. */ Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
value -1 is returned and the global variable errno is set to indicate the
error. */
void int
ut_usectime( ut_usectime(
/*========*/ /*========*/
/* out: 0 on success, -1 otherwise */
ulint* sec, /* out: seconds since the Epoch */ ulint* sec, /* out: seconds since the Epoch */
ulint* ms) /* out: microseconds since the Epoch+*sec */ ulint* ms) /* out: microseconds since the Epoch+*sec */
{ {
struct timeval tv; struct timeval tv;
int ret;
int errno_gettimeofday;
int i;
for (i = 0; i < 10; i++) {
ut_gettimeofday(&tv, NULL); ret = ut_gettimeofday(&tv, NULL);
if (ret == -1) {
errno_gettimeofday = errno;
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: gettimeofday(): %s\n",
strerror(errno_gettimeofday));
os_thread_sleep(100000); /* 0.1 sec */
errno = errno_gettimeofday;
} else {
break;
}
}
if (ret != -1) {
*sec = (ulint) tv.tv_sec; *sec = (ulint) tv.tv_sec;
*ms = (ulint) tv.tv_usec; *ms = (ulint) tv.tv_usec;
}
return(ret);
} }
/************************************************************** /**************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment