mirror of
https://github.com/MariaDB/server.git
synced 2025-07-02 14:22:51 +03:00
Merge remote-tracking branch 'origin/10.1' into 10.2
This commit is contained in:
@ -2177,6 +2177,66 @@ t1 CREATE TABLE `t1` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-15308
|
||||||
|
# Assertion `ha_alter_info->alter_info->drop_list.elements > 0' failed
|
||||||
|
# in ha_innodb::prepare_inplace_alter_table
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN b;
|
||||||
|
Warnings:
|
||||||
|
Note 1091 Can't DROP FOREIGN KEY `fk`; check that it exists
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN b;
|
||||||
|
Warnings:
|
||||||
|
Note 1091 Can't DROP INDEX `fk`; check that it exists
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT, b INT, c INT, KEY(c)) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN c;
|
||||||
|
Warnings:
|
||||||
|
Note 1091 Can't DROP FOREIGN KEY `fk`; check that it exists
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT, b INT, c INT, KEY c1(c)) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP INDEX c1;
|
||||||
|
Warnings:
|
||||||
|
Note 1091 Can't DROP FOREIGN KEY `fk`; check that it exists
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` int(11) DEFAULT NULL,
|
||||||
|
`c` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN IF EXISTS c;
|
||||||
|
Warnings:
|
||||||
|
Note 1091 Can't DROP INDEX `fk`; check that it exists
|
||||||
|
Note 1091 Can't DROP COLUMN `c`; check that it exists
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.0 tests
|
# End of 10.0 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -809,10 +809,9 @@ LOAD INDEX INTO CACHE t3;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
mysqltest_db1.t3 preload_keys status OK
|
mysqltest_db1.t3 preload_keys status OK
|
||||||
#
|
#
|
||||||
# RENAME (doesn't work for temporary tables, thus should fail).
|
# RENAME should work for temporary tables
|
||||||
#
|
#
|
||||||
RENAME TABLE t3 TO t3_1;
|
RENAME TABLE t3 TO t3_1;
|
||||||
ERROR 42000: INSERT, CREATE command denied to user 'mysqltest_u1'@'localhost' for table 't3_1'
|
|
||||||
#
|
#
|
||||||
# HANDLER OPEN/READ/CLOSE.
|
# HANDLER OPEN/READ/CLOSE.
|
||||||
#
|
#
|
||||||
|
@ -78,3 +78,69 @@ ERROR HY000: 'test.v1' is not BASE TABLE
|
|||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
CREATE OR REPLACE TABLE t1 (a INT);
|
||||||
|
CREATE OR REPLACE TABLE t2 (a INT);
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE t1_tmp (b INT);
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE t2_tmp (b INT);
|
||||||
|
rename table t1 to t2;
|
||||||
|
ERROR 42S01: Table 't2' already exists
|
||||||
|
rename table t1 to tmp, tmp to t2;
|
||||||
|
ERROR 42S01: Table 't2' already exists
|
||||||
|
rename table t1_tmp to t2_tmp;
|
||||||
|
ERROR 42S01: Table 't2_tmp' already exists
|
||||||
|
rename table t1_tmp to tmp, tmp to t2_tmp;
|
||||||
|
ERROR 42S01: Table 't2_tmp' already exists
|
||||||
|
show create table t1_tmp;
|
||||||
|
Table Create Table
|
||||||
|
t1_tmp CREATE TEMPORARY TABLE `t1_tmp` (
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
show create table t2_tmp;
|
||||||
|
Table Create Table
|
||||||
|
t2_tmp CREATE TEMPORARY TABLE `t2_tmp` (
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
rename table t1 to t1_tmp;
|
||||||
|
rename table t2_tmp to t2;
|
||||||
|
rename table t2 to tmp, tmp to t2;
|
||||||
|
rename table t1_tmp to tmp, tmp to t1_tmp;
|
||||||
|
show tables;
|
||||||
|
Tables_in_test
|
||||||
|
t1_tmp
|
||||||
|
t2
|
||||||
|
SHOW CREATE TABLE t1_tmp;
|
||||||
|
Table Create Table
|
||||||
|
t1_tmp CREATE TEMPORARY TABLE `t1_tmp` (
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1_tmp;
|
||||||
|
SHOW CREATE TABLE t1_tmp;
|
||||||
|
Table Create Table
|
||||||
|
t1_tmp CREATE TABLE `t1_tmp` (
|
||||||
|
`a` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1_tmp;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TEMPORARY TABLE `t2` (
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t2;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`a` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t2;
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
insert into t1 values (1);
|
||||||
|
CREATE TEMPORARY TABLE t1 (b INT);
|
||||||
|
insert into t1 values (2);
|
||||||
|
RENAME TABLE t1 TO tmp, t1 TO t2;
|
||||||
|
select * from tmp;
|
||||||
|
b
|
||||||
|
2
|
||||||
|
select * from t2;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
drop table tmp,t2;
|
||||||
|
11
mysql-test/r/statistics_close.result
Normal file
11
mysql-test/r/statistics_close.result
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
connect con1,localhost,root,,test;
|
||||||
|
RENAME TABLE t1 TO t2;
|
||||||
|
connection default;
|
||||||
|
FLUSH TABLES;
|
||||||
|
connection con1;
|
||||||
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
Warnings:
|
||||||
|
Note 1051 Unknown table 'test.t1'
|
35
mysql-test/suite/galera/r/galera_encrypt_tmp_files.result
Normal file
35
mysql-test/suite/galera/r/galera_encrypt_tmp_files.result
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
|
||||||
|
VARIABLE_VALUE = 'Synced'
|
||||||
|
1
|
||||||
|
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||||
|
VARIABLE_VALUE = 2
|
||||||
|
1
|
||||||
|
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
|
||||||
|
VARIABLE_VALUE = 'Synced'
|
||||||
|
1
|
||||||
|
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||||
|
VARIABLE_VALUE = 2
|
||||||
|
1
|
||||||
|
SELECT COUNT(*) = 1 FROM t1;
|
||||||
|
COUNT(*) = 1
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`col1` int(11) NOT NULL,
|
||||||
|
`col2` varchar(64) NOT NULL DEFAULT '',
|
||||||
|
`col3` varchar(32) NOT NULL DEFAULT '0',
|
||||||
|
`col4` varchar(64) NOT NULL DEFAULT '',
|
||||||
|
`col5` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
|
`col6` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`col7` varchar(64) NOT NULL DEFAULT '',
|
||||||
|
`col8` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
|
`col9` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
|
`col10` text NOT NULL,
|
||||||
|
`col11` varchar(255) NOT NULL DEFAULT '',
|
||||||
|
`col12` tinyint(4) NOT NULL DEFAULT '1'
|
||||||
|
) ;
|
||||||
|
create table t2 (test int);
|
||||||
|
insert into t2 values (1);
|
||||||
|
drop table t1,t2;
|
8
mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf
Normal file
8
mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
!include ../galera_2nodes.cnf
|
||||||
|
[mysqld]
|
||||||
|
|
||||||
|
encrypt-tmp-files = 1
|
||||||
|
plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO
|
||||||
|
file-key-management
|
||||||
|
loose-file-key-management-filename= @ENV.MYSQL_TEST_DIR/std_data/keys.txt
|
||||||
|
log-bin
|
57
mysql-test/suite/galera/t/galera_encrypt_tmp_files.test
Normal file
57
mysql-test/suite/galera/t/galera_encrypt_tmp_files.test
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# This file tests that mariadb cluster should not crash when encrypt_tmp_file
|
||||||
|
# is enabled
|
||||||
|
|
||||||
|
--source include/galera_cluster.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
|
||||||
|
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||||
|
|
||||||
|
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
|
||||||
|
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||||
|
|
||||||
|
SELECT COUNT(*) = 1 FROM t1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`col1` int(11) NOT NULL,
|
||||||
|
`col2` varchar(64) NOT NULL DEFAULT '',
|
||||||
|
`col3` varchar(32) NOT NULL DEFAULT '0',
|
||||||
|
`col4` varchar(64) NOT NULL DEFAULT '',
|
||||||
|
`col5` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
|
`col6` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`col7` varchar(64) NOT NULL DEFAULT '',
|
||||||
|
`col8` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
|
`col9` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
|
`col10` text NOT NULL,
|
||||||
|
`col11` varchar(255) NOT NULL DEFAULT '',
|
||||||
|
`col12` tinyint(4) NOT NULL DEFAULT '1'
|
||||||
|
) ;
|
||||||
|
|
||||||
|
#Although we just need $counter >= 907 for IO_CACHE to use
|
||||||
|
#encrypted temp file. Just on safe side I am using $counter
|
||||||
|
# = 1100
|
||||||
|
--disable_query_log
|
||||||
|
--let $counter=1100
|
||||||
|
--let $query= (1,'test','test','test',0,0,'-1',0,0,'','',-1)
|
||||||
|
while($counter)
|
||||||
|
{
|
||||||
|
--let $query= $query ,(1,'test','test','test',0,0,'-1',0,0,'','',-1)
|
||||||
|
--dec $counter
|
||||||
|
}
|
||||||
|
--let $query= INSERT INTO t1 values $query ;
|
||||||
|
--eval $query
|
||||||
|
--enable_query_log
|
||||||
|
#INSERT INTO `t1` VALUE
|
||||||
|
|
||||||
|
create table t2 (test int);
|
||||||
|
insert into t2 values (1);
|
||||||
|
|
||||||
|
drop table t1,t2;
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
--source include/galera_cluster.inc
|
--source include/galera_cluster.inc
|
||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_perfschema.inc
|
||||||
|
|
||||||
# Save original auto_increment_offset values.
|
# Save original auto_increment_offset values.
|
||||||
--let $node_1=node_1
|
--let $node_1=node_1
|
||||||
|
@ -99,3 +99,13 @@ f2
|
|||||||
3
|
3
|
||||||
unlock tables;
|
unlock tables;
|
||||||
DROP TABLE t1,t2,tmp;
|
DROP TABLE t1,t2,tmp;
|
||||||
|
#
|
||||||
|
# MDEV-10378 Assertion `trn' failed in virtual int ha_maria::start_stmt
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (f1 VARCHAR(3), f2 INT, pk INT, PRIMARY KEY (pk)) ENGINE=Aria;
|
||||||
|
INSERT INTO t1 VALUES ('foo',10,1), ('foo',1,2);
|
||||||
|
LOCK TABLE t1 WRITE;
|
||||||
|
ALTER TABLE t1 ADD UNIQUE KEY (f1);
|
||||||
|
ERROR 23000: Duplicate entry 'foo' for key 'f1'
|
||||||
|
ALTER TABLE t1 ADD KEY (f2);
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -105,3 +105,15 @@ INSERT INTO t2 (f2) SELECT f3 FROM tmp AS tmp_alias;
|
|||||||
select * from t2;
|
select * from t2;
|
||||||
unlock tables;
|
unlock tables;
|
||||||
DROP TABLE t1,t2,tmp;
|
DROP TABLE t1,t2,tmp;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-10378 Assertion `trn' failed in virtual int ha_maria::start_stmt
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (f1 VARCHAR(3), f2 INT, pk INT, PRIMARY KEY (pk)) ENGINE=Aria;
|
||||||
|
INSERT INTO t1 VALUES ('foo',10,1), ('foo',1,2);
|
||||||
|
LOCK TABLE t1 WRITE;
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
ALTER TABLE t1 ADD UNIQUE KEY (f1);
|
||||||
|
ALTER TABLE t1 ADD KEY (f2);
|
||||||
|
DROP TABLE t1;
|
||||||
|
36
mysql-test/suite/rpl/r/rename.result
Normal file
36
mysql-test/suite/rpl/r/rename.result
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
#
|
||||||
|
# MDEV-16229 Replication aborts with ER_VIEW_SELECT_TMPTABLE after
|
||||||
|
# half-failed RENAME
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
CREATE TEMPORARY TABLE t1 (b INT);
|
||||||
|
RENAME TABLE t1 TO tmp, tmp TO t1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TEMPORARY TABLE `t1` (
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
CREATE VIEW v AS SELECT * FROM t1;
|
||||||
|
ERROR HY000: View's SELECT refers to a temporary table 't1'
|
||||||
|
RENAME TABLE t1 TO tmp, t1 TO t2;
|
||||||
|
SHOW CREATE TABLE tmp;
|
||||||
|
Table Create Table
|
||||||
|
tmp CREATE TEMPORARY TABLE `tmp` (
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`a` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
CREATE VIEW v AS SELECT * FROM tmp;
|
||||||
|
ERROR HY000: View's SELECT refers to a temporary table 'tmp'
|
||||||
|
CREATE VIEW v AS SELECT * FROM t2;
|
||||||
|
connection slave;
|
||||||
|
connection master;
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP TABLE tmp;
|
||||||
|
DROP TABLE t2;
|
||||||
|
include/rpl_end.inc
|
33
mysql-test/suite/rpl/t/rename.test
Normal file
33
mysql-test/suite/rpl/t/rename.test
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
--source include/have_binlog_format_mixed.inc
|
||||||
|
--source include/master-slave.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-16229 Replication aborts with ER_VIEW_SELECT_TMPTABLE after
|
||||||
|
--echo # half-failed RENAME
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
CREATE TEMPORARY TABLE t1 (b INT);
|
||||||
|
RENAME TABLE t1 TO tmp, tmp TO t1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
--error ER_VIEW_SELECT_TMPTABLE
|
||||||
|
CREATE VIEW v AS SELECT * FROM t1;
|
||||||
|
|
||||||
|
RENAME TABLE t1 TO tmp, t1 TO t2;
|
||||||
|
SHOW CREATE TABLE tmp;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
--error ER_VIEW_SELECT_TMPTABLE
|
||||||
|
CREATE VIEW v AS SELECT * FROM tmp;
|
||||||
|
CREATE VIEW v AS SELECT * FROM t2;
|
||||||
|
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP TABLE tmp;
|
||||||
|
DROP TABLE t2;
|
||||||
|
|
||||||
|
--source include/rpl_end.inc
|
@ -1807,6 +1807,37 @@ ALTER TABLE t1 CONVERT TO CHARACTER SET utf8;
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-15308
|
||||||
|
--echo # Assertion `ha_alter_info->alter_info->drop_list.elements > 0' failed
|
||||||
|
--echo # in ha_innodb::prepare_inplace_alter_table
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN b;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN b;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT, c INT, KEY(c)) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN c;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT, c INT, KEY c1(c)) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP INDEX c1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN IF EXISTS c;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.0 tests
|
--echo # End of 10.0 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -873,9 +873,8 @@ CACHE INDEX t3 IN keycache1;
|
|||||||
LOAD INDEX INTO CACHE t3;
|
LOAD INDEX INTO CACHE t3;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # RENAME (doesn't work for temporary tables, thus should fail).
|
--echo # RENAME should work for temporary tables
|
||||||
--echo #
|
--echo #
|
||||||
--error ER_TABLEACCESS_DENIED_ERROR
|
|
||||||
RENAME TABLE t3 TO t3_1;
|
RENAME TABLE t3 TO t3_1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -95,3 +95,49 @@ drop table t1;
|
|||||||
|
|
||||||
--source include/wait_until_count_sessions.inc
|
--source include/wait_until_count_sessions.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test of rename with temporary tables
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE OR REPLACE TABLE t1 (a INT);
|
||||||
|
CREATE OR REPLACE TABLE t2 (a INT);
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE t1_tmp (b INT);
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE t2_tmp (b INT);
|
||||||
|
|
||||||
|
# Can't rename table over another one
|
||||||
|
--error ER_TABLE_EXISTS_ERROR
|
||||||
|
rename table t1 to t2;
|
||||||
|
--error ER_TABLE_EXISTS_ERROR
|
||||||
|
rename table t1 to tmp, tmp to t2;
|
||||||
|
--error ER_TABLE_EXISTS_ERROR
|
||||||
|
rename table t1_tmp to t2_tmp;
|
||||||
|
--error ER_TABLE_EXISTS_ERROR
|
||||||
|
rename table t1_tmp to tmp, tmp to t2_tmp;
|
||||||
|
|
||||||
|
show create table t1_tmp;
|
||||||
|
show create table t2_tmp;
|
||||||
|
|
||||||
|
# The following should work
|
||||||
|
rename table t1 to t1_tmp;
|
||||||
|
rename table t2_tmp to t2;
|
||||||
|
rename table t2 to tmp, tmp to t2;
|
||||||
|
rename table t1_tmp to tmp, tmp to t1_tmp;
|
||||||
|
show tables;
|
||||||
|
SHOW CREATE TABLE t1_tmp;
|
||||||
|
drop table t1_tmp;
|
||||||
|
SHOW CREATE TABLE t1_tmp;
|
||||||
|
drop table t1_tmp;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
drop table t2;
|
||||||
|
SHOW CREATE TABLE t2;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
insert into t1 values (1);
|
||||||
|
CREATE TEMPORARY TABLE t1 (b INT);
|
||||||
|
insert into t1 values (2);
|
||||||
|
RENAME TABLE t1 TO tmp, t1 TO t2;
|
||||||
|
select * from tmp;
|
||||||
|
select * from t2;
|
||||||
|
drop table tmp,t2;
|
||||||
|
|
||||||
|
18
mysql-test/t/statistics_close.test
Normal file
18
mysql-test/t/statistics_close.test
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#
|
||||||
|
# MDEV-16123 ASAN heap-use-after-free handler::ha_index_or_rnd_end
|
||||||
|
# MDEV-13828 Segmentation fault on RENAME TABLE
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
--connect (con1,localhost,root,,test)
|
||||||
|
--send
|
||||||
|
RENAME TABLE t1 TO t2;
|
||||||
|
--connection default
|
||||||
|
FLUSH TABLES;
|
||||||
|
--connection con1
|
||||||
|
--reap
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
--disconnect con1
|
||||||
|
--connection default
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
@ -49,8 +49,8 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
|
|||||||
|
|
||||||
if (pos_in_file == info->end_of_file)
|
if (pos_in_file == info->end_of_file)
|
||||||
{
|
{
|
||||||
info->read_pos= info->read_end= info->buffer;
|
/* reading past EOF should not empty the cache */
|
||||||
info->pos_in_file= pos_in_file;
|
info->read_pos= info->read_end;
|
||||||
info->error= 0;
|
info->error= 0;
|
||||||
DBUG_RETURN(MY_TEST(Count));
|
DBUG_RETURN(MY_TEST(Count));
|
||||||
}
|
}
|
||||||
|
@ -426,7 +426,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
HA_CHECK_OPT* check_opt,
|
HA_CHECK_OPT* check_opt,
|
||||||
const char *operator_name,
|
const char *operator_name,
|
||||||
thr_lock_type lock_type,
|
thr_lock_type lock_type,
|
||||||
bool open_for_modify,
|
bool org_open_for_modify,
|
||||||
bool repair_table_use_frm,
|
bool repair_table_use_frm,
|
||||||
uint extra_open_options,
|
uint extra_open_options,
|
||||||
int (*prepare_func)(THD *, TABLE_LIST *,
|
int (*prepare_func)(THD *, TABLE_LIST *,
|
||||||
@ -488,10 +488,11 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
for (table= tables; table; table= table->next_local)
|
for (table= tables; table; table= table->next_local)
|
||||||
{
|
{
|
||||||
char table_name[SAFE_NAME_LEN*2+2];
|
char table_name[SAFE_NAME_LEN*2+2];
|
||||||
char* db = table->db;
|
char *db= table->db;
|
||||||
bool fatal_error=0;
|
bool fatal_error=0;
|
||||||
bool open_error;
|
bool open_error;
|
||||||
bool collect_eis= FALSE;
|
bool collect_eis= FALSE;
|
||||||
|
bool open_for_modify= org_open_for_modify;
|
||||||
|
|
||||||
DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
|
DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
|
||||||
strxmov(table_name, db, ".", table->table_name, NullS);
|
strxmov(table_name, db, ".", table->table_name, NullS);
|
||||||
@ -1159,7 +1160,7 @@ send_result_message:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Error path, a admin command failed. */
|
/* Error path, a admin command failed. */
|
||||||
if (thd->transaction_rollback_request)
|
if (thd->transaction_rollback_request || fatal_error)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Unlikely, but transaction rollback was requested by one of storage
|
Unlikely, but transaction rollback was requested by one of storage
|
||||||
|
@ -4262,6 +4262,12 @@ public:
|
|||||||
|
|
||||||
/* Members related to temporary tables. */
|
/* Members related to temporary tables. */
|
||||||
public:
|
public:
|
||||||
|
/* Opened table states. */
|
||||||
|
enum Temporary_table_state {
|
||||||
|
TMP_TABLE_IN_USE,
|
||||||
|
TMP_TABLE_NOT_IN_USE,
|
||||||
|
TMP_TABLE_ANY
|
||||||
|
};
|
||||||
bool has_thd_temporary_tables();
|
bool has_thd_temporary_tables();
|
||||||
|
|
||||||
TABLE *create_and_open_tmp_table(handlerton *hton,
|
TABLE *create_and_open_tmp_table(handlerton *hton,
|
||||||
@ -4271,8 +4277,10 @@ public:
|
|||||||
const char *table_name,
|
const char *table_name,
|
||||||
bool open_in_engine);
|
bool open_in_engine);
|
||||||
|
|
||||||
TABLE *find_temporary_table(const char *db, const char *table_name);
|
TABLE *find_temporary_table(const char *db, const char *table_name,
|
||||||
TABLE *find_temporary_table(const TABLE_LIST *tl);
|
Temporary_table_state state= TMP_TABLE_IN_USE);
|
||||||
|
TABLE *find_temporary_table(const TABLE_LIST *tl,
|
||||||
|
Temporary_table_state state= TMP_TABLE_IN_USE);
|
||||||
|
|
||||||
TMP_TABLE_SHARE *find_tmp_table_share_w_base_key(const char *key,
|
TMP_TABLE_SHARE *find_tmp_table_share_w_base_key(const char *key,
|
||||||
uint key_length);
|
uint key_length);
|
||||||
@ -4299,13 +4307,6 @@ private:
|
|||||||
/* Whether a lock has been acquired? */
|
/* Whether a lock has been acquired? */
|
||||||
bool m_tmp_tables_locked;
|
bool m_tmp_tables_locked;
|
||||||
|
|
||||||
/* Opened table states. */
|
|
||||||
enum Temporary_table_state {
|
|
||||||
TMP_TABLE_IN_USE,
|
|
||||||
TMP_TABLE_NOT_IN_USE,
|
|
||||||
TMP_TABLE_ANY
|
|
||||||
};
|
|
||||||
|
|
||||||
bool has_temporary_tables();
|
bool has_temporary_tables();
|
||||||
uint create_tmp_table_def_key(char *key, const char *db,
|
uint create_tmp_table_def_key(char *key, const char *db,
|
||||||
const char *table_name);
|
const char *table_name);
|
||||||
|
@ -155,10 +155,11 @@ static void mysql_ha_close_table(SQL_HANDLER *handler)
|
|||||||
{
|
{
|
||||||
THD *thd= handler->thd;
|
THD *thd= handler->thd;
|
||||||
TABLE *table= handler->table;
|
TABLE *table= handler->table;
|
||||||
|
DBUG_ENTER("mysql_ha_close_table");
|
||||||
|
|
||||||
/* check if table was already closed */
|
/* check if table was already closed */
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
if (!table->s->tmp_table)
|
if (!table->s->tmp_table)
|
||||||
{
|
{
|
||||||
@ -183,6 +184,7 @@ static void mysql_ha_close_table(SQL_HANDLER *handler)
|
|||||||
}
|
}
|
||||||
my_free(handler->lock);
|
my_free(handler->lock);
|
||||||
handler->init();
|
handler->init();
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -763,6 +763,8 @@ void init_update_queries(void)
|
|||||||
There are other statements that deal with temporary tables and open
|
There are other statements that deal with temporary tables and open
|
||||||
them, but which are not listed here. The thing is that the order of
|
them, but which are not listed here. The thing is that the order of
|
||||||
pre-opening temporary tables for those statements is somewhat custom.
|
pre-opening temporary tables for those statements is somewhat custom.
|
||||||
|
|
||||||
|
Note that SQLCOM_RENAME_TABLE should not be in this list!
|
||||||
*/
|
*/
|
||||||
sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES;
|
sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES;
|
||||||
sql_command_flags[SQLCOM_DROP_TABLE]|= CF_PREOPEN_TMP_TABLES;
|
sql_command_flags[SQLCOM_DROP_TABLE]|= CF_PREOPEN_TMP_TABLES;
|
||||||
@ -776,7 +778,6 @@ void init_update_queries(void)
|
|||||||
sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES;
|
sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES;
|
||||||
sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES;
|
sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES;
|
||||||
sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES;
|
sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES;
|
||||||
sql_command_flags[SQLCOM_RENAME_TABLE]|= CF_PREOPEN_TMP_TABLES;
|
|
||||||
sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES;
|
sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES;
|
||||||
sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES;
|
sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES;
|
||||||
sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES;
|
sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES;
|
||||||
@ -6525,6 +6526,60 @@ static bool execute_show_status(THD *thd, TABLE_LIST *all_tables)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Find out if a table is a temporary table
|
||||||
|
|
||||||
|
A table is a temporary table if it's a temporary table or
|
||||||
|
there has been before a temporary table that has been renamed
|
||||||
|
to the current name.
|
||||||
|
|
||||||
|
Some examples:
|
||||||
|
A->B B is a temporary table if and only if A is a temp.
|
||||||
|
A->B, B->C Second B is temp if A is temp
|
||||||
|
A->B, A->C Second A can't be temp as if A was temp then B is temp
|
||||||
|
and Second A can only be a normal table. C is also not temp
|
||||||
|
*/
|
||||||
|
|
||||||
|
static TABLE *find_temporary_table_for_rename(THD *thd,
|
||||||
|
TABLE_LIST *first_table,
|
||||||
|
TABLE_LIST *cur_table)
|
||||||
|
{
|
||||||
|
TABLE_LIST *table;
|
||||||
|
TABLE *res= 0;
|
||||||
|
bool found= 0;
|
||||||
|
DBUG_ENTER("find_temporary_table_for_rename");
|
||||||
|
|
||||||
|
/* Find last instance when cur_table is in TO part */
|
||||||
|
for (table= first_table;
|
||||||
|
table != cur_table;
|
||||||
|
table= table->next_local->next_local)
|
||||||
|
{
|
||||||
|
TABLE_LIST *next= table->next_local;
|
||||||
|
|
||||||
|
if (!strcmp(table->get_db_name(), cur_table->get_db_name()) &&
|
||||||
|
!strcmp(table->get_table_name(), cur_table->get_table_name()))
|
||||||
|
{
|
||||||
|
/* Table was moved away, can't be same as 'table' */
|
||||||
|
found= 1;
|
||||||
|
res= 0; // Table can't be a temporary table
|
||||||
|
}
|
||||||
|
if (!strcmp(next->get_db_name(), cur_table->get_db_name()) &&
|
||||||
|
!strcmp(next->get_table_name(), cur_table->get_table_name()))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Table has matching name with new name of this table. cur_table should
|
||||||
|
have same temporary type as this table.
|
||||||
|
*/
|
||||||
|
found= 1;
|
||||||
|
res= table->table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
res= thd->find_temporary_table(table, THD::TMP_TABLE_ANY);
|
||||||
|
DBUG_RETURN(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
|
static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
|
||||||
TABLE_LIST *all_tables)
|
TABLE_LIST *all_tables)
|
||||||
{
|
{
|
||||||
@ -6541,13 +6596,19 @@ static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
|
|||||||
&table->next_local->grant.m_internal,
|
&table->next_local->grant.m_internal,
|
||||||
0, 0))
|
0, 0))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* check if these are refering to temporary tables */
|
||||||
|
table->table= find_temporary_table_for_rename(thd, first_table, table);
|
||||||
|
table->next_local->table= table->table;
|
||||||
|
|
||||||
TABLE_LIST old_list, new_list;
|
TABLE_LIST old_list, new_list;
|
||||||
/*
|
/*
|
||||||
we do not need initialize old_list and new_list because we will
|
we do not need initialize old_list and new_list because we will
|
||||||
come table[0] and table->next[0] there
|
copy table[0] and table->next[0] there
|
||||||
*/
|
*/
|
||||||
old_list= table[0];
|
old_list= table[0];
|
||||||
new_list= table->next_local[0];
|
new_list= table->next_local[0];
|
||||||
|
|
||||||
if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, FALSE, 1, FALSE) ||
|
if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, FALSE, 1, FALSE) ||
|
||||||
(!test_all_bits(table->next_local->grant.privilege,
|
(!test_all_bits(table->next_local->grant.privilege,
|
||||||
INSERT_ACL | CREATE_ACL) &&
|
INSERT_ACL | CREATE_ACL) &&
|
||||||
|
@ -221,7 +221,7 @@ do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table,
|
|||||||
new_alias= (lower_case_table_names == 2) ? new_table->alias :
|
new_alias= (lower_case_table_names == 2) ? new_table->alias :
|
||||||
new_table->table_name;
|
new_table->table_name;
|
||||||
|
|
||||||
if (is_temporary_table(new_table))
|
if (thd->find_temporary_table(new_table, THD::TMP_TABLE_ANY))
|
||||||
{
|
{
|
||||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
|
||||||
DBUG_RETURN(1); // This can't be skipped
|
DBUG_RETURN(1); // This can't be skipped
|
||||||
|
@ -1519,7 +1519,8 @@ public:
|
|||||||
|
|
||||||
~Stat_table_write_iter()
|
~Stat_table_write_iter()
|
||||||
{
|
{
|
||||||
cleanup();
|
/* Ensure that cleanup has been run */
|
||||||
|
DBUG_ASSERT(rowid_buf == 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5888,10 +5888,28 @@ drop_create_field:
|
|||||||
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
|
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
|
||||||
Alter_drop *drop;
|
Alter_drop *drop;
|
||||||
bool remove_drop;
|
bool remove_drop;
|
||||||
|
ulonglong left_flags= 0;
|
||||||
while ((drop= drop_it++))
|
while ((drop= drop_it++))
|
||||||
{
|
{
|
||||||
|
ulonglong cur_flag= 0;
|
||||||
|
switch (drop->type) {
|
||||||
|
case Alter_drop::COLUMN:
|
||||||
|
cur_flag= Alter_info::ALTER_DROP_COLUMN;
|
||||||
|
break;
|
||||||
|
case Alter_drop::FOREIGN_KEY:
|
||||||
|
cur_flag= Alter_info::DROP_FOREIGN_KEY;
|
||||||
|
break;
|
||||||
|
case Alter_drop::KEY:
|
||||||
|
cur_flag= Alter_info::ALTER_DROP_INDEX;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!drop->drop_if_exists)
|
if (!drop->drop_if_exists)
|
||||||
|
{
|
||||||
|
left_flags|= cur_flag;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
remove_drop= TRUE;
|
remove_drop= TRUE;
|
||||||
if (drop->type == Alter_drop::COLUMN)
|
if (drop->type == Alter_drop::COLUMN)
|
||||||
{
|
{
|
||||||
@ -5980,12 +5998,15 @@ drop_create_field:
|
|||||||
ER_THD(thd, ER_CANT_DROP_FIELD_OR_KEY),
|
ER_THD(thd, ER_CANT_DROP_FIELD_OR_KEY),
|
||||||
drop->type_name(), drop->name);
|
drop->type_name(), drop->name);
|
||||||
drop_it.remove();
|
drop_it.remove();
|
||||||
if (alter_info->drop_list.is_empty())
|
|
||||||
alter_info->flags&= ~(Alter_info::ALTER_DROP_COLUMN |
|
|
||||||
Alter_info::ALTER_DROP_INDEX |
|
|
||||||
Alter_info::DROP_FOREIGN_KEY);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
left_flags|= cur_flag;
|
||||||
}
|
}
|
||||||
|
/* Reset state to what's left in drop list */
|
||||||
|
alter_info->flags&= ~(Alter_info::ALTER_DROP_COLUMN |
|
||||||
|
Alter_info::ALTER_DROP_INDEX |
|
||||||
|
Alter_info::DROP_FOREIGN_KEY);
|
||||||
|
alter_info->flags|= left_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ALTER TABLE ADD KEY IF NOT EXISTS */
|
/* ALTER TABLE ADD KEY IF NOT EXISTS */
|
||||||
|
@ -99,12 +99,14 @@ TABLE *THD::create_and_open_tmp_table(handlerton *hton,
|
|||||||
|
|
||||||
@param db [IN] Database name
|
@param db [IN] Database name
|
||||||
@param table_name [IN] Table name
|
@param table_name [IN] Table name
|
||||||
|
@param state [IN] State of temp table to open
|
||||||
|
|
||||||
@return Success Pointer to first used table instance.
|
@return Success Pointer to first used table instance.
|
||||||
Failure NULL
|
Failure NULL
|
||||||
*/
|
*/
|
||||||
TABLE *THD::find_temporary_table(const char *db,
|
TABLE *THD::find_temporary_table(const char *db,
|
||||||
const char *table_name)
|
const char *table_name,
|
||||||
|
Temporary_table_state state)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("THD::find_temporary_table");
|
DBUG_ENTER("THD::find_temporary_table");
|
||||||
|
|
||||||
@ -121,7 +123,7 @@ TABLE *THD::find_temporary_table(const char *db,
|
|||||||
key_length= create_tmp_table_def_key(key, db, table_name);
|
key_length= create_tmp_table_def_key(key, db, table_name);
|
||||||
|
|
||||||
locked= lock_temporary_tables();
|
locked= lock_temporary_tables();
|
||||||
table = find_temporary_table(key, key_length, TMP_TABLE_IN_USE);
|
table= find_temporary_table(key, key_length, state);
|
||||||
if (locked)
|
if (locked)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(m_tmp_tables_locked);
|
DBUG_ASSERT(m_tmp_tables_locked);
|
||||||
@ -140,16 +142,12 @@ TABLE *THD::find_temporary_table(const char *db,
|
|||||||
@return Success Pointer to first used table instance.
|
@return Success Pointer to first used table instance.
|
||||||
Failure NULL
|
Failure NULL
|
||||||
*/
|
*/
|
||||||
TABLE *THD::find_temporary_table(const TABLE_LIST *tl)
|
TABLE *THD::find_temporary_table(const TABLE_LIST *tl,
|
||||||
|
Temporary_table_state state)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("THD::find_temporary_table");
|
DBUG_ENTER("THD::find_temporary_table");
|
||||||
|
TABLE *table= find_temporary_table(tl->get_db_name(), tl->get_table_name(),
|
||||||
if (!has_temporary_tables())
|
state);
|
||||||
{
|
|
||||||
DBUG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
TABLE *table= find_temporary_table(tl->get_db_name(), tl->get_table_name());
|
|
||||||
DBUG_RETURN(table);
|
DBUG_RETURN(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ C_MODE_START
|
|||||||
#include "ma_checkpoint.h"
|
#include "ma_checkpoint.h"
|
||||||
#include "ma_recovery.h"
|
#include "ma_recovery.h"
|
||||||
C_MODE_END
|
C_MODE_END
|
||||||
|
#include "ma_trnman.h"
|
||||||
|
|
||||||
//#include "sql_priv.h"
|
//#include "sql_priv.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
@ -1393,7 +1394,8 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Reset trn, that may have been set by repair */
|
/* Reset trn, that may have been set by repair */
|
||||||
_ma_set_trn_for_table(file, old_trn);
|
if (old_trn && old_trn != file->trn)
|
||||||
|
_ma_set_trn_for_table(file, old_trn);
|
||||||
thd_proc_info(thd, old_proc_info);
|
thd_proc_info(thd, old_proc_info);
|
||||||
thd_progress_end(thd);
|
thd_progress_end(thd);
|
||||||
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
|
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
|
||||||
@ -1527,7 +1529,8 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
|
|||||||
error=maria_zerofill(param, file, share->open_file_name.str);
|
error=maria_zerofill(param, file, share->open_file_name.str);
|
||||||
|
|
||||||
/* Reset trn, that may have been set by repair */
|
/* Reset trn, that may have been set by repair */
|
||||||
_ma_set_trn_for_table(file, old_trn);
|
if (old_trn && old_trn != file->trn)
|
||||||
|
_ma_set_trn_for_table(file, old_trn);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
@ -1770,7 +1773,8 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
|
|||||||
maria_lock_database(file, F_UNLCK);
|
maria_lock_database(file, F_UNLCK);
|
||||||
|
|
||||||
/* Reset trn, that may have been set by repair */
|
/* Reset trn, that may have been set by repair */
|
||||||
_ma_set_trn_for_table(file, old_trn);
|
if (old_trn && old_trn != file->trn)
|
||||||
|
_ma_set_trn_for_table(file, old_trn);
|
||||||
error= error ? HA_ADMIN_FAILED :
|
error= error ? HA_ADMIN_FAILED :
|
||||||
(optimize_done ?
|
(optimize_done ?
|
||||||
(write_log_record_for_repair(param, file) ? HA_ADMIN_FAILED :
|
(write_log_record_for_repair(param, file) ? HA_ADMIN_FAILED :
|
||||||
@ -2581,9 +2585,12 @@ int ha_maria::extra(enum ha_extra_function operation)
|
|||||||
without calling commit/rollback in between. If file->trn is not set
|
without calling commit/rollback in between. If file->trn is not set
|
||||||
we can't remove file->share from the transaction list in the extra() call.
|
we can't remove file->share from the transaction list in the extra() call.
|
||||||
|
|
||||||
We also ensure that we set file->trn to 0 if THD_TRN is 0 as in
|
In current code we don't have to do this for HA_EXTRA_PREPARE_FOR_RENAME
|
||||||
this case we have already freed the trn. This can happen when one
|
as this is only used the intermediate table used by ALTER TABLE which
|
||||||
implicit_commit() is called as part of alter table.
|
is not part of the transaction (it's not in the TRN list). Better to
|
||||||
|
keep this for now, to not break anything in a stable release.
|
||||||
|
When HA_EXTRA_PREPARE_FOR_RENAME is not handled below, we can change
|
||||||
|
the warnings in _ma_remove_table_from_trnman() to asserts.
|
||||||
|
|
||||||
table->in_use is not set in the case this is a done as part of closefrm()
|
table->in_use is not set in the case this is a done as part of closefrm()
|
||||||
as part of drop table.
|
as part of drop table.
|
||||||
@ -2596,7 +2603,7 @@ int ha_maria::extra(enum ha_extra_function operation)
|
|||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
THD *thd= table->in_use;
|
||||||
TRN *trn= THD_TRN;
|
TRN *trn= THD_TRN;
|
||||||
_ma_set_trn_for_table(file, trn);
|
_ma_set_tmp_trn_for_table(file, trn);
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(file->s->base.born_transactional || file->trn == 0 ||
|
DBUG_ASSERT(file->s->base.born_transactional || file->trn == 0 ||
|
||||||
file->trn == &dummy_transaction_object);
|
file->trn == &dummy_transaction_object);
|
||||||
@ -2712,6 +2719,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
|||||||
if (file->trn)
|
if (file->trn)
|
||||||
{
|
{
|
||||||
/* This can only happen with tables created with clone() */
|
/* This can only happen with tables created with clone() */
|
||||||
|
DBUG_PRINT("info",("file->trn: %p", file->trn));
|
||||||
trnman_increment_locked_tables(file->trn);
|
trnman_increment_locked_tables(file->trn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2732,7 +2740,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRN *trn= THD_TRN;
|
TRN *trn= (file->trn != &dummy_transaction_object ? file->trn : 0);
|
||||||
/* End of transaction */
|
/* End of transaction */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2747,8 +2755,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
|||||||
*/
|
*/
|
||||||
if (_ma_reenable_logging_for_table(file, TRUE))
|
if (_ma_reenable_logging_for_table(file, TRUE))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
/** @todo zero file->trn also in commit and rollback */
|
_ma_reset_trn_for_table(file);
|
||||||
_ma_set_trn_for_table(file, NULL); // Safety
|
|
||||||
/*
|
/*
|
||||||
Ensure that file->state points to the current number of rows. This
|
Ensure that file->state points to the current number of rows. This
|
||||||
is needed if someone calls maria_info() without first doing an
|
is needed if someone calls maria_info() without first doing an
|
||||||
@ -2804,13 +2811,6 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)
|
|||||||
DBUG_ASSERT(lock_type != TL_UNLOCK);
|
DBUG_ASSERT(lock_type != TL_UNLOCK);
|
||||||
DBUG_ASSERT(file->trn == trn);
|
DBUG_ASSERT(file->trn == trn);
|
||||||
|
|
||||||
/*
|
|
||||||
If there was an implicit commit under this LOCK TABLES by a previous
|
|
||||||
statement (like a DDL), at least if that previous statement was about a
|
|
||||||
different ha_maria than 'this' then this->file->trn is a stale
|
|
||||||
pointer. We fix it:
|
|
||||||
*/
|
|
||||||
_ma_set_trn_for_table(file, trn);
|
|
||||||
/*
|
/*
|
||||||
As external_lock() was already called, don't increment locked_tables.
|
As external_lock() was already called, don't increment locked_tables.
|
||||||
Note that we call the function below possibly several times when
|
Note that we call the function below possibly several times when
|
||||||
@ -2835,6 +2835,23 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reset THD_TRN and all file->trn related to the transaction
|
||||||
|
This is needed as some calls, like extra() or external_lock() may access
|
||||||
|
it before next transaction is started
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void reset_thd_trn(THD *thd, MARIA_HA *first_table)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("reset_thd_trn");
|
||||||
|
THD_TRN= NULL;
|
||||||
|
for (MARIA_HA *table= first_table; table ;
|
||||||
|
table= table->trn_next)
|
||||||
|
_ma_reset_trn_for_table(table);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an implicit commit of the Maria transaction and creates a new
|
Performs an implicit commit of the Maria transaction and creates a new
|
||||||
one.
|
one.
|
||||||
@ -2858,10 +2875,10 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
|
|||||||
TRN *trn;
|
TRN *trn;
|
||||||
int error;
|
int error;
|
||||||
uint locked_tables;
|
uint locked_tables;
|
||||||
DYNAMIC_ARRAY used_tables;
|
|
||||||
extern my_bool plugins_are_initialized;
|
extern my_bool plugins_are_initialized;
|
||||||
|
MARIA_HA *used_tables, *trn_next;
|
||||||
DBUG_ENTER("ha_maria::implicit_commit");
|
DBUG_ENTER("ha_maria::implicit_commit");
|
||||||
|
|
||||||
if (!maria_hton || !plugins_are_initialized || !(trn= THD_TRN))
|
if (!maria_hton || !plugins_are_initialized || !(trn= THD_TRN))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
if (!new_trn && (thd->locked_tables_mode == LTM_LOCK_TABLES ||
|
if (!new_trn && (thd->locked_tables_mode == LTM_LOCK_TABLES ||
|
||||||
@ -2879,48 +2896,16 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
|
|||||||
|
|
||||||
locked_tables= trnman_has_locked_tables(trn);
|
locked_tables= trnman_has_locked_tables(trn);
|
||||||
|
|
||||||
if (new_trn && trn && trn->used_tables)
|
used_tables= (MARIA_HA*) trn->used_instances;
|
||||||
{
|
|
||||||
MARIA_USED_TABLES *tables;
|
|
||||||
/*
|
|
||||||
Save locked tables so that we can move them to another transaction
|
|
||||||
We are using a dynamic array as locked_tables in some cases can be
|
|
||||||
smaller than the used_tables list (for example when the server does
|
|
||||||
early unlock of tables.
|
|
||||||
*/
|
|
||||||
|
|
||||||
my_init_dynamic_array2(&used_tables, sizeof(MARIA_SHARE*), (void*) 0,
|
|
||||||
locked_tables, 8, MYF(MY_THREAD_SPECIFIC));
|
|
||||||
for (tables= (MARIA_USED_TABLES*) trn->used_tables;
|
|
||||||
tables;
|
|
||||||
tables= tables->next)
|
|
||||||
{
|
|
||||||
if (tables->share->base.born_transactional)
|
|
||||||
{
|
|
||||||
if (insert_dynamic(&used_tables, (uchar*) &tables->share))
|
|
||||||
{
|
|
||||||
error= HA_ERR_OUT_OF_MEM;
|
|
||||||
goto end_and_free;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bzero(&used_tables, sizeof(used_tables));
|
|
||||||
|
|
||||||
error= 0;
|
error= 0;
|
||||||
if (unlikely(ma_commit(trn)))
|
if (unlikely(ma_commit(trn)))
|
||||||
error= 1;
|
error= 1;
|
||||||
if (!new_trn)
|
if (!new_trn)
|
||||||
{
|
{
|
||||||
/*
|
reset_thd_trn(thd, used_tables);
|
||||||
To be extra safe, we should also reset file->trn for all open
|
|
||||||
tables as some calls, like extra() may access it. We take care
|
|
||||||
of this in extra() by resetting file->trn if THD_TRN is 0.
|
|
||||||
*/
|
|
||||||
THD_TRN= NULL;
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We need to create a new transaction and put it in THD_TRN. Indeed,
|
We need to create a new transaction and put it in THD_TRN. Indeed,
|
||||||
tables may be under LOCK TABLES, and so they will start the next
|
tables may be under LOCK TABLES, and so they will start the next
|
||||||
@ -2930,8 +2915,9 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
|
|||||||
THD_TRN= trn;
|
THD_TRN= trn;
|
||||||
if (unlikely(trn == NULL))
|
if (unlikely(trn == NULL))
|
||||||
{
|
{
|
||||||
|
reset_thd_trn(thd, used_tables);
|
||||||
error= HA_ERR_OUT_OF_MEM;
|
error= HA_ERR_OUT_OF_MEM;
|
||||||
goto end_and_free;
|
goto end;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Move all locked tables to the new transaction
|
Move all locked tables to the new transaction
|
||||||
@ -2941,35 +2927,25 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
|
|||||||
in check table, we use the table without calling start_stmt().
|
in check table, we use the table without calling start_stmt().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint i;
|
for (MARIA_HA *handler= used_tables; handler ;
|
||||||
for (i= 0 ; i < used_tables.elements ; i++)
|
handler= trn_next)
|
||||||
{
|
{
|
||||||
MARIA_SHARE *share;
|
trn_next= handler->trn_next;
|
||||||
LIST *handlers;
|
DBUG_ASSERT(handler->s->base.born_transactional);
|
||||||
|
|
||||||
share= *(dynamic_element(&used_tables, i, MARIA_SHARE**));
|
/* If handler uses versioning */
|
||||||
/* Find table instances that was used in this transaction */
|
if (handler->s->lock_key_trees)
|
||||||
for (handlers= share->open_list; handlers; handlers= handlers->next)
|
|
||||||
{
|
{
|
||||||
MARIA_HA *handler= (MARIA_HA*) handlers->data;
|
/* _ma_set_trn_for_table() will be called indirectly */
|
||||||
if (handler->external_ref &&
|
if (_ma_setup_live_state(handler))
|
||||||
((TABLE*) handler->external_ref)->in_use == thd)
|
error= HA_ERR_OUT_OF_MEM;
|
||||||
{
|
|
||||||
_ma_set_trn_for_table(handler, trn);
|
|
||||||
/* If handler uses versioning */
|
|
||||||
if (handler->s->lock_key_trees)
|
|
||||||
{
|
|
||||||
if (_ma_setup_live_state(handler))
|
|
||||||
error= HA_ERR_OUT_OF_MEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
_ma_set_trn_for_table(handler, trn);
|
||||||
}
|
}
|
||||||
/* This is just a commit, tables stay locked if they were: */
|
/* This is just a commit, tables stay locked if they were: */
|
||||||
trnman_reset_locked_tables(trn, locked_tables);
|
trnman_reset_locked_tables(trn, locked_tables);
|
||||||
|
|
||||||
end_and_free:
|
|
||||||
delete_dynamic(&used_tables);
|
|
||||||
end:
|
end:
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
@ -3342,10 +3318,10 @@ static int maria_commit(handlerton *hton __attribute__ ((unused)),
|
|||||||
trnman_set_flags(trn, trnman_get_flags(trn) & ~TRN_STATE_INFO_LOGGED);
|
trnman_set_flags(trn, trnman_get_flags(trn) & ~TRN_STATE_INFO_LOGGED);
|
||||||
|
|
||||||
/* statement or transaction ? */
|
/* statement or transaction ? */
|
||||||
if ((thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && !all)
|
if ((thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
|
||||||
|
!all)
|
||||||
DBUG_RETURN(0); // end of statement
|
DBUG_RETURN(0); // end of statement
|
||||||
DBUG_PRINT("info", ("THD_TRN set to 0x0"));
|
reset_thd_trn(thd, (MARIA_HA*) trn->used_instances);
|
||||||
THD_TRN= 0;
|
|
||||||
DBUG_RETURN(ma_commit(trn)); // end of transaction
|
DBUG_RETURN(ma_commit(trn)); // end of transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3362,8 +3338,7 @@ static int maria_rollback(handlerton *hton __attribute__ ((unused)),
|
|||||||
trnman_rollback_statement(trn);
|
trnman_rollback_statement(trn);
|
||||||
DBUG_RETURN(0); // end of statement
|
DBUG_RETURN(0); // end of statement
|
||||||
}
|
}
|
||||||
DBUG_PRINT("info", ("THD_TRN set to 0x0"));
|
reset_thd_trn(thd, (MARIA_HA*) trn->used_instances);
|
||||||
THD_TRN= 0;
|
|
||||||
DBUG_RETURN(trnman_rollback_trn(trn) ?
|
DBUG_RETURN(trnman_rollback_trn(trn) ?
|
||||||
HA_ERR_OUT_OF_MEM : 0); // end of transaction
|
HA_ERR_OUT_OF_MEM : 0); // end of transaction
|
||||||
}
|
}
|
||||||
|
@ -193,6 +193,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
DsMrr_impl ds_mrr;
|
DsMrr_impl ds_mrr;
|
||||||
friend ICP_RESULT index_cond_func_maria(void *arg);
|
friend ICP_RESULT index_cond_func_maria(void *arg);
|
||||||
|
friend void reset_thd_trn(THD *thd);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* HA_MARIA_INCLUDED */
|
#endif /* HA_MARIA_INCLUDED */
|
||||||
|
@ -271,6 +271,7 @@
|
|||||||
#include "maria_def.h"
|
#include "maria_def.h"
|
||||||
#include "ma_blockrec.h"
|
#include "ma_blockrec.h"
|
||||||
#include "trnman.h"
|
#include "trnman.h"
|
||||||
|
#include "ma_trnman.h"
|
||||||
#include "ma_key_recover.h"
|
#include "ma_key_recover.h"
|
||||||
#include "ma_recovery_util.h"
|
#include "ma_recovery_util.h"
|
||||||
#include <lf.h>
|
#include <lf.h>
|
||||||
@ -7525,7 +7526,7 @@ void maria_ignore_trids(MARIA_HA *info)
|
|||||||
if (info->s->base.born_transactional)
|
if (info->s->base.born_transactional)
|
||||||
{
|
{
|
||||||
if (!info->trn)
|
if (!info->trn)
|
||||||
_ma_set_trn_for_table(info, &dummy_transaction_object);
|
_ma_set_tmp_trn_for_table(info, &dummy_transaction_object);
|
||||||
/* Ignore transaction id when row is read */
|
/* Ignore transaction id when row is read */
|
||||||
info->trn->min_read_from= ~(TrID) 0;
|
info->trn->min_read_from= ~(TrID) 0;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ int maria_close(register MARIA_HA *info)
|
|||||||
|
|
||||||
/* Check that we have unlocked key delete-links properly */
|
/* Check that we have unlocked key delete-links properly */
|
||||||
DBUG_ASSERT(info->key_del_used == 0);
|
DBUG_ASSERT(info->key_del_used == 0);
|
||||||
|
/* Check that file is not part of any uncommited transactions */
|
||||||
|
DBUG_ASSERT(info->trn == 0 || info->trn == &dummy_transaction_object);
|
||||||
|
|
||||||
if (share->reopen == 1)
|
if (share->reopen == 1)
|
||||||
{
|
{
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "maria_def.h"
|
#include "maria_def.h"
|
||||||
#include "trnman.h"
|
#include "trnman.h"
|
||||||
|
#include "ma_trnman.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
writes a COMMIT record to log and commits transaction in memory
|
writes a COMMIT record to log and commits transaction in memory
|
||||||
@ -43,9 +44,9 @@ int ma_commit(TRN *trn)
|
|||||||
COMMIT record) and this is not an issue as
|
COMMIT record) and this is not an issue as
|
||||||
* transaction's updates were not made visible to other transactions
|
* transaction's updates were not made visible to other transactions
|
||||||
* "commit ok" was not sent to client
|
* "commit ok" was not sent to client
|
||||||
Alternatively, Recovery might commit trn (if MY_MIN(rec_lsn) is before COMMIT
|
Alternatively, Recovery might commit trn (if MY_MIN(rec_lsn) is before
|
||||||
record), which is ok too. All in all it means that "trn committed" is not
|
COMMIT record), which is ok too. All in all it means that "trn committed"
|
||||||
100% equal to "COMMIT record written".
|
is not 100% equal to "COMMIT record written".
|
||||||
- if COMMIT record is written after trnman_commit_trn():
|
- if COMMIT record is written after trnman_commit_trn():
|
||||||
if crash happens between the two, trn will be rolled back which is an
|
if crash happens between the two, trn will be rolled back which is an
|
||||||
issue (transaction's updates were made visible to other transactions).
|
issue (transaction's updates were made visible to other transactions).
|
||||||
@ -93,7 +94,12 @@ int ma_commit(TRN *trn)
|
|||||||
|
|
||||||
int maria_commit(MARIA_HA *info)
|
int maria_commit(MARIA_HA *info)
|
||||||
{
|
{
|
||||||
return info->s->now_transactional ? ma_commit(info->trn) : 0;
|
TRN *trn;
|
||||||
|
if (!info->s->now_transactional)
|
||||||
|
return 0;
|
||||||
|
trn= info->trn;
|
||||||
|
info->trn= 0; /* checked in maria_close() */
|
||||||
|
return ma_commit(trn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -120,10 +126,7 @@ int maria_begin(MARIA_HA *info)
|
|||||||
TRN *trn= trnman_new_trn(0);
|
TRN *trn= trnman_new_trn(0);
|
||||||
if (unlikely(!trn))
|
if (unlikely(!trn))
|
||||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||||
|
|
||||||
DBUG_PRINT("info", ("TRN set to %p", trn));
|
|
||||||
_ma_set_trn_for_table(info, trn);
|
_ma_set_trn_for_table(info, trn);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
|
|||||||
_ma_decrement_open_count(info, 0);
|
_ma_decrement_open_count(info, 0);
|
||||||
if (info->trn)
|
if (info->trn)
|
||||||
{
|
{
|
||||||
_ma_remove_table_from_trnman(share, info->trn);
|
_ma_remove_table_from_trnman(info);
|
||||||
/* Ensure we don't point to the deleted data in trn */
|
/* Ensure we don't point to the deleted data in trn */
|
||||||
info->state= info->state_start= &share->state.state;
|
info->state= info->state_start= &share->state.state;
|
||||||
}
|
}
|
||||||
@ -409,7 +409,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
|
|||||||
if (info->trn)
|
if (info->trn)
|
||||||
{
|
{
|
||||||
mysql_mutex_lock(&share->intern_lock);
|
mysql_mutex_lock(&share->intern_lock);
|
||||||
_ma_remove_table_from_trnman(share, info->trn);
|
_ma_remove_table_from_trnman(info);
|
||||||
/* Ensure we don't point to the deleted data in trn */
|
/* Ensure we don't point to the deleted data in trn */
|
||||||
info->state= info->state_start= &share->state.state;
|
info->state= info->state_start= &share->state.state;
|
||||||
mysql_mutex_unlock(&share->intern_lock);
|
mysql_mutex_unlock(&share->intern_lock);
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include "ma_sp_defs.h"
|
#include "ma_sp_defs.h"
|
||||||
#include "ma_rt_index.h"
|
#include "ma_rt_index.h"
|
||||||
#include "ma_blockrec.h"
|
#include "ma_blockrec.h"
|
||||||
|
#include "trnman.h"
|
||||||
|
#include "ma_trnman.h"
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
#include "ma_crypt.h"
|
#include "ma_crypt.h"
|
||||||
|
|
||||||
@ -184,7 +186,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share,
|
|||||||
if (!share->base.born_transactional) /* For transactional ones ... */
|
if (!share->base.born_transactional) /* For transactional ones ... */
|
||||||
{
|
{
|
||||||
/* ... force crash if no trn given */
|
/* ... force crash if no trn given */
|
||||||
_ma_set_trn_for_table(&info, &dummy_transaction_object);
|
_ma_set_tmp_trn_for_table(&info, &dummy_transaction_object);
|
||||||
info.state= &share->state.state; /* Change global values by default */
|
info.state= &share->state.state; /* Change global values by default */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -66,7 +66,7 @@ my_bool _ma_setup_live_state(MARIA_HA *info)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
trn= info->trn;
|
trn= info->trn;
|
||||||
for (tables= (MARIA_USED_TABLES*) info->trn->used_tables;
|
for (tables= (MARIA_USED_TABLES*) trn->used_tables;
|
||||||
tables;
|
tables;
|
||||||
tables= tables->next)
|
tables= tables->next)
|
||||||
{
|
{
|
||||||
@ -551,6 +551,7 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
|
|||||||
my_free(tables);
|
my_free(tables);
|
||||||
}
|
}
|
||||||
trn->used_tables= 0;
|
trn->used_tables= 0;
|
||||||
|
trn->used_instances= 0;
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,18 +566,25 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
|
|||||||
share->internal_lock must be locked when function is called
|
share->internal_lock must be locked when function is called
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
|
void _ma_remove_table_from_trnman(MARIA_HA *info)
|
||||||
{
|
{
|
||||||
|
MARIA_SHARE *share= info->s;
|
||||||
|
TRN *trn= info->trn;
|
||||||
MARIA_USED_TABLES *tables, **prev;
|
MARIA_USED_TABLES *tables, **prev;
|
||||||
|
MARIA_HA *handler, **prev_file;
|
||||||
DBUG_ENTER("_ma_remove_table_from_trnman");
|
DBUG_ENTER("_ma_remove_table_from_trnman");
|
||||||
DBUG_PRINT("enter", ("trn: %p used_tables: %p share: %p in_trans: %d",
|
DBUG_PRINT("enter", ("trn: %p used_tables: %p share: %p in_trans: %d",
|
||||||
trn, trn->used_tables, share, share->in_trans));
|
trn, trn->used_tables, share, share->in_trans));
|
||||||
|
|
||||||
mysql_mutex_assert_owner(&share->intern_lock);
|
mysql_mutex_assert_owner(&share->intern_lock);
|
||||||
|
|
||||||
|
if (trn == &dummy_transaction_object)
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
for (prev= (MARIA_USED_TABLES**) (char*) &trn->used_tables, tables= *prev;
|
/* First remove share from used_tables */
|
||||||
tables;
|
for (prev= (MARIA_USED_TABLES**) (char*) &trn->used_tables;
|
||||||
tables= *prev)
|
(tables= *prev);
|
||||||
|
prev= &tables->next)
|
||||||
{
|
{
|
||||||
if (tables->share == share)
|
if (tables->share == share)
|
||||||
{
|
{
|
||||||
@ -585,8 +593,36 @@ void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
|
|||||||
my_free(tables);
|
my_free(tables);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prev= &tables->next;
|
|
||||||
}
|
}
|
||||||
|
if (tables != 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This can only happens in case of rename of intermediate table as
|
||||||
|
part of alter table
|
||||||
|
*/
|
||||||
|
DBUG_PRINT("warning", ("share: %p where not in used_tables_list", share));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unlink table from used_instances */
|
||||||
|
for (prev_file= (MARIA_HA**) &trn->used_instances;
|
||||||
|
(handler= *prev_file);
|
||||||
|
prev_file= &handler->trn_next)
|
||||||
|
{
|
||||||
|
if (handler == info)
|
||||||
|
{
|
||||||
|
*prev_file= info->trn_next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (handler != 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This can only happens in case of rename of intermediate table as
|
||||||
|
part of alter table
|
||||||
|
*/
|
||||||
|
DBUG_PRINT("warning", ("table: %p where not in used_instances", info));
|
||||||
|
}
|
||||||
|
info->trn= 0; /* Not part of trans anymore */
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,5 +84,5 @@ my_bool _ma_row_visible_non_transactional_table(MARIA_HA *info);
|
|||||||
my_bool _ma_row_visible_transactional_table(MARIA_HA *info);
|
my_bool _ma_row_visible_transactional_table(MARIA_HA *info);
|
||||||
void _ma_remove_not_visible_states_with_lock(struct st_maria_share *share,
|
void _ma_remove_not_visible_states_with_lock(struct st_maria_share *share,
|
||||||
my_bool all);
|
my_bool all);
|
||||||
void _ma_remove_table_from_trnman(struct st_maria_share *share, TRN *trn);
|
void _ma_remove_table_from_trnman(MARIA_HA *info);
|
||||||
void _ma_reset_history(struct st_maria_share *share);
|
void _ma_reset_history(struct st_maria_share *share);
|
||||||
|
65
storage/maria/ma_trnman.h
Normal file
65
storage/maria/ma_trnman.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#ifndef _ma_trnman_h
|
||||||
|
#define _ma_trnman_h
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets table's trn and prints debug information
|
||||||
|
Links table into used_instances if new_trn is not 0
|
||||||
|
|
||||||
|
@param tbl MARIA_HA of table
|
||||||
|
@param newtrn what to put into tbl->trn
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void _ma_set_trn_for_table(MARIA_HA *tbl, TRN *newtrn)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info",("table: %p trn: %p -> %p",
|
||||||
|
tbl, tbl->trn, newtrn));
|
||||||
|
|
||||||
|
/* check that we are not calling this twice in a row */
|
||||||
|
DBUG_ASSERT(newtrn->used_instances != (void*) tbl);
|
||||||
|
|
||||||
|
tbl->trn= newtrn;
|
||||||
|
/* Link into used list */
|
||||||
|
tbl->trn_next= (MARIA_HA*) newtrn->used_instances;
|
||||||
|
newtrn->used_instances= tbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Same as _ma_set_trn_for_table(), but don't link table into used_instance list
|
||||||
|
Used when we want to temporary set trn for a table in extra()
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void _ma_set_tmp_trn_for_table(MARIA_HA *tbl, TRN *newtrn)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info",("table: %p trn: %p -> %p",
|
||||||
|
tbl, tbl->trn, newtrn));
|
||||||
|
tbl->trn= newtrn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reset TRN in table
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void _ma_reset_trn_for_table(MARIA_HA *tbl)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info",("table: %p trn: %p -> NULL", tbl, tbl->trn));
|
||||||
|
tbl->trn= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ma_trnman_h */
|
@ -601,6 +601,7 @@ struct st_maria_handler
|
|||||||
{
|
{
|
||||||
MARIA_SHARE *s; /* Shared between open:s */
|
MARIA_SHARE *s; /* Shared between open:s */
|
||||||
struct st_ma_transaction *trn; /* Pointer to active transaction */
|
struct st_ma_transaction *trn; /* Pointer to active transaction */
|
||||||
|
struct st_maria_handler *trn_next;
|
||||||
MARIA_STATUS_INFO *state, state_save;
|
MARIA_STATUS_INFO *state, state_save;
|
||||||
MARIA_STATUS_INFO *state_start; /* State at start of transaction */
|
MARIA_STATUS_INFO *state_start; /* State at start of transaction */
|
||||||
MARIA_USED_TABLES *used_tables;
|
MARIA_USED_TABLES *used_tables;
|
||||||
@ -861,19 +862,6 @@ struct st_maria_handler
|
|||||||
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)
|
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)
|
||||||
#define _ma_have_versioning(info) ((info)->row_flag & ROW_FLAG_TRANSID)
|
#define _ma_have_versioning(info) ((info)->row_flag & ROW_FLAG_TRANSID)
|
||||||
|
|
||||||
/**
|
|
||||||
Sets table's trn and prints debug information
|
|
||||||
@param tbl MARIA_HA of table
|
|
||||||
@param newtrn what to put into tbl->trn
|
|
||||||
@note cast of newtrn is because %p of NULL gives warning (NULL is int)
|
|
||||||
*/
|
|
||||||
#define _ma_set_trn_for_table(tbl, newtrn) do { \
|
|
||||||
DBUG_PRINT("info",("table: %p trn: %p -> %p", \
|
|
||||||
(tbl), (tbl)->trn, (void *)(newtrn))); \
|
|
||||||
(tbl)->trn= (newtrn); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#define MARIA_MIN_BLOCK_LENGTH 20 /* Because of delete-link */
|
#define MARIA_MIN_BLOCK_LENGTH 20 /* Because of delete-link */
|
||||||
/* Don't use to small record-blocks */
|
/* Don't use to small record-blocks */
|
||||||
#define MARIA_EXTEND_BLOCK_LENGTH 20
|
#define MARIA_EXTEND_BLOCK_LENGTH 20
|
||||||
|
@ -357,6 +357,7 @@ TRN *trnman_new_trn(WT_THD *wt)
|
|||||||
trn->commit_trid= MAX_TRID;
|
trn->commit_trid= MAX_TRID;
|
||||||
trn->rec_lsn= trn->undo_lsn= trn->first_undo_lsn= 0;
|
trn->rec_lsn= trn->undo_lsn= trn->first_undo_lsn= 0;
|
||||||
trn->used_tables= 0;
|
trn->used_tables= 0;
|
||||||
|
trn->used_instances= 0;
|
||||||
|
|
||||||
trn->locked_tables= 0;
|
trn->locked_tables= 0;
|
||||||
trn->flags= 0;
|
trn->flags= 0;
|
||||||
|
@ -46,7 +46,8 @@ struct st_ma_transaction
|
|||||||
LF_PINS *pins;
|
LF_PINS *pins;
|
||||||
WT_THD *wt;
|
WT_THD *wt;
|
||||||
mysql_mutex_t state_lock;
|
mysql_mutex_t state_lock;
|
||||||
void *used_tables; /**< Tables used by transaction */
|
void *used_tables; /**< Table shares used by transaction */
|
||||||
|
void *used_instances; /* table files used by transaction */
|
||||||
TRN *next, *prev;
|
TRN *next, *prev;
|
||||||
TrID trid, min_read_from, commit_trid;
|
TrID trid, min_read_from, commit_trid;
|
||||||
LSN rec_lsn, undo_lsn;
|
LSN rec_lsn, undo_lsn;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2014, 2017, MariaDB Corporation.
|
Copyright (c) 2014, 2018, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@ -4922,9 +4922,11 @@ i_s_innodb_buffer_page_fill(
|
|||||||
|
|
||||||
mutex_enter(&dict_sys->mutex);
|
mutex_enter(&dict_sys->mutex);
|
||||||
|
|
||||||
if (const dict_index_t* index =
|
const dict_index_t* index =
|
||||||
dict_index_get_if_in_cache_low(
|
dict_index_get_if_in_cache_low(
|
||||||
page_info->index_id)) {
|
page_info->index_id);
|
||||||
|
|
||||||
|
if (index) {
|
||||||
table_name_end = innobase_convert_name(
|
table_name_end = innobase_convert_name(
|
||||||
table_name, sizeof(table_name),
|
table_name, sizeof(table_name),
|
||||||
index->table_name,
|
index->table_name,
|
||||||
@ -4947,7 +4949,10 @@ i_s_innodb_buffer_page_fill(
|
|||||||
|
|
||||||
OK(ret);
|
OK(ret);
|
||||||
|
|
||||||
fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_notnull();
|
if (index) {
|
||||||
|
fields[IDX_BUFFER_PAGE_TABLE_NAME]
|
||||||
|
->set_notnull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store(
|
OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store(
|
||||||
@ -5621,9 +5626,11 @@ i_s_innodb_buf_page_lru_fill(
|
|||||||
|
|
||||||
mutex_enter(&dict_sys->mutex);
|
mutex_enter(&dict_sys->mutex);
|
||||||
|
|
||||||
if (const dict_index_t* index =
|
const dict_index_t* index =
|
||||||
dict_index_get_if_in_cache_low(
|
dict_index_get_if_in_cache_low(
|
||||||
page_info->index_id)) {
|
page_info->index_id);
|
||||||
|
|
||||||
|
if (index) {
|
||||||
table_name_end = innobase_convert_name(
|
table_name_end = innobase_convert_name(
|
||||||
table_name, sizeof(table_name),
|
table_name, sizeof(table_name),
|
||||||
index->table_name,
|
index->table_name,
|
||||||
@ -5646,7 +5653,10 @@ i_s_innodb_buf_page_lru_fill(
|
|||||||
|
|
||||||
OK(ret);
|
OK(ret);
|
||||||
|
|
||||||
fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_notnull();
|
if (index) {
|
||||||
|
fields[IDX_BUF_LRU_PAGE_TABLE_NAME]
|
||||||
|
->set_notnull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store(
|
OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store(
|
||||||
|
@ -187,10 +187,76 @@ void mdev9044()
|
|||||||
close_cached_file(&info);
|
close_cached_file(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 2 Reads (with my_b_fill) in cache makes second read to fail */
|
||||||
|
void mdev10259()
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
uchar buf[200];
|
||||||
|
memset(buf, FILL, sizeof(buf));
|
||||||
|
|
||||||
|
diag("MDEV-10259- mysqld crash with certain statement length and order with"
|
||||||
|
" Galera and encrypt-tmp-files=1");
|
||||||
|
|
||||||
|
init_io_cache_encryption();
|
||||||
|
|
||||||
|
res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0);
|
||||||
|
ok(res == 0, "open_cached_file" INFO_TAIL);
|
||||||
|
|
||||||
|
res= my_b_write(&info, buf, sizeof(buf));
|
||||||
|
ok(res == 0 && info.pos_in_file == 0, "200 write" INFO_TAIL);
|
||||||
|
|
||||||
|
res= my_b_flush_io_cache(&info, 1);
|
||||||
|
ok(res == 0, "flush" INFO_TAIL);
|
||||||
|
|
||||||
|
ulong saved_pos= my_b_tell(&info);
|
||||||
|
res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
|
||||||
|
ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
|
||||||
|
|
||||||
|
res= my_b_fill(&info);
|
||||||
|
ok(res == 200, "fill" INFO_TAIL);
|
||||||
|
|
||||||
|
res= my_b_fill(&info);
|
||||||
|
ok(res == 0, "fill" INFO_TAIL);
|
||||||
|
|
||||||
|
res= my_b_fill(&info);
|
||||||
|
ok(res == 0, "fill" INFO_TAIL);
|
||||||
|
|
||||||
|
res= reinit_io_cache(&info, WRITE_CACHE, saved_pos, 0, 0);
|
||||||
|
ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL);
|
||||||
|
|
||||||
|
res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
|
||||||
|
ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
|
||||||
|
|
||||||
|
ok(200 == my_b_bytes_in_cache(&info),"my_b_bytes_in_cache == 200");
|
||||||
|
|
||||||
|
res= my_b_fill(&info);
|
||||||
|
ok(res == 0, "fill" INFO_TAIL);
|
||||||
|
|
||||||
|
res= my_b_fill(&info);
|
||||||
|
ok(res == 0, "fill" INFO_TAIL);
|
||||||
|
|
||||||
|
res= my_b_fill(&info);
|
||||||
|
ok(res == 0, "fill" INFO_TAIL);
|
||||||
|
|
||||||
|
res= reinit_io_cache(&info, WRITE_CACHE, saved_pos, 0, 0);
|
||||||
|
ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL);
|
||||||
|
|
||||||
|
res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
|
||||||
|
ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
|
||||||
|
|
||||||
|
ok(200 == my_b_bytes_in_cache(&info),"my_b_bytes_in_cache == 200");
|
||||||
|
|
||||||
|
res= my_b_read(&info, buf, sizeof(buf)) || data_bad(buf, sizeof(buf));
|
||||||
|
ok(res == 0 && info.pos_in_file == 0, "large read" INFO_TAIL);
|
||||||
|
|
||||||
|
close_cached_file(&info);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc __attribute__((unused)),char *argv[])
|
int main(int argc __attribute__((unused)),char *argv[])
|
||||||
{
|
{
|
||||||
MY_INIT(argv[0]);
|
MY_INIT(argv[0]);
|
||||||
plan(29);
|
plan(46);
|
||||||
|
|
||||||
/* temp files with and without encryption */
|
/* temp files with and without encryption */
|
||||||
encrypt_tmp_files= 1;
|
encrypt_tmp_files= 1;
|
||||||
@ -202,6 +268,10 @@ int main(int argc __attribute__((unused)),char *argv[])
|
|||||||
/* regression tests */
|
/* regression tests */
|
||||||
mdev9044();
|
mdev9044();
|
||||||
|
|
||||||
|
encrypt_tmp_files= 1;
|
||||||
|
mdev10259();
|
||||||
|
encrypt_tmp_files= 0;
|
||||||
|
|
||||||
my_end(0);
|
my_end(0);
|
||||||
return exit_status();
|
return exit_status();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user