mirror of
https://github.com/MariaDB/server.git
synced 2025-04-21 22:55:35 +02:00

While ALTER thread tries to notify SELECT thread about lock conflict it accesses its TABLE object (THD::notify_shared_lock()) and lock data (mysql_lock_abort_for_thread()). As part of accessing lock data it calls ha_partition::store_lock() which iterates over all partitions and does their store_lock(). The problem is SELECT opened 2 read partitions, but ha_partition::store_lock() tries to access all partitions as indicated in m_tot_parts which is 4. So the last 2 partitions m_file[2] and m_file[3] are uninitialized and store_lock() accesses uninitialized data. The code in ha_partition::store_lock() does this wrong handling to use all partitions specifically for the case of mysql_lock_abort_for_thread(), this is conducted with comment: /* This can be called from get_lock_data() in mysql_lock_abort_for_thread(), even when thd != table->in_use. In that case don't use partition pruning, but use all partitions instead to avoid using another threads structures. */ if (thd != table->in_use) { for (i= 0; i < m_tot_parts; i++) to= m_file[i]->store_lock(thd, to, lock_type); } The explanation is "to avoid using another threads structures" does not really explain why this change was needed. The change was originally introduced by: commit 9b7cccaf319 Author: Mattias Jonsson <mattias.jonsson@oracle.com> Date: Wed May 30 00:14:39 2012 +0200 WL#4443: final code change for dlenevs review. - Don't use pruning in lock_count(). - Don't use pruning in store_lock() if not owning thd. - Renamed is_fields_used_in_trigger to is_fields_updated_in_trigger() and check if they may be updated. - moved out mark_fields_used(TRG_EVENT_UPDATE) from mark_columns_needed_for_update(). And reverted the changed call order. And call mark_fields_used(TRG_EVENT_UPDATE) instead. which also fails to explain the rationale of the change. The original idea of WL#4443 is to reduce locks and this change does not happen to serve this goal. So reverting this change restores original behaviour of using only partitions marked for use and fixes invalid access to uninitialized data.
279 lines
8.6 KiB
Text
279 lines
8.6 KiB
Text
--source include/have_partition.inc
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1, t2;
|
|
--enable_warnings
|
|
|
|
# These tests is only useful when running on MyISAM,
|
|
# due to DATA/INDEX directory, non transactional behavior, tests with MyISAM
|
|
# files etc.
|
|
|
|
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
|
|
|
--echo #
|
|
--echo # BUG#11933226 - 60681: CHECKSUM TABLE RETURNS 0 FOR PARTITIONED TABLE
|
|
--echo #
|
|
CREATE TABLE t1 (
|
|
i INT
|
|
)
|
|
ENGINE=MyISAM
|
|
PARTITION BY RANGE (i)
|
|
(PARTITION p3 VALUES LESS THAN (3),
|
|
PARTITION p5 VALUES LESS THAN (5),
|
|
PARTITION pMax VALUES LESS THAN MAXVALUE);
|
|
INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6);
|
|
CHECKSUM TABLE t1;
|
|
ALTER TABLE t1 CHECKSUM = 1;
|
|
CHECKSUM TABLE t1 EXTENDED;
|
|
--echo # Before patch this returned 0!
|
|
CHECKSUM TABLE t1;
|
|
SHOW CREATE TABLE t1;
|
|
DROP TABLE t1;
|
|
|
|
--echo # Same test without partitioning
|
|
CREATE TABLE t1 (
|
|
i INT
|
|
) ENGINE=MyISAM;
|
|
SHOW CREATE TABLE t1;
|
|
INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6);
|
|
CHECKSUM TABLE t1;
|
|
ALTER TABLE t1 CHECKSUM = 1;
|
|
CHECKSUM TABLE t1 EXTENDED;
|
|
CHECKSUM TABLE t1;
|
|
SHOW CREATE TABLE t1;
|
|
DROP TABLE t1;
|
|
|
|
#
|
|
# Disabled by WL#946: binary format for timestamp column is not compatible.
|
|
# So the trick with replacing FRM file does not work any more.
|
|
#--echo #
|
|
#--echo # Bug#50036: Inconsistent errors when using TIMESTAMP
|
|
#--echo # columns/expressions
|
|
#
|
|
#--echo # Added test with existing TIMESTAMP partitioning (when it was allowed).
|
|
#CREATE TABLE t1 (a TIMESTAMP)
|
|
#ENGINE = MyISAM
|
|
#PARTITION BY HASH (UNIX_TIMESTAMP(a));
|
|
#INSERT INTO t1 VALUES ('2000-01-02 03:04:05');
|
|
#--sorted_result
|
|
#SELECT * FROM t1;
|
|
#FLUSH TABLES;
|
|
#--echo # replacing t1.frm with TO_DAYS(a) which was allowed earlier.
|
|
#--remove_file $MYSQLD_DATADIR/test/t1.frm
|
|
#--copy_file std_data/parts/t1TIMESTAMP.frm $MYSQLD_DATADIR/test/t1.frm
|
|
#--echo # Disable warnings, since the result would differ when running with
|
|
#--echo # --ps-protocol (only for the 'SELECT * FROM t1' statement).
|
|
#--disable_warnings
|
|
#--sorted_result
|
|
#SELECT * FROM t1;
|
|
#--enable_warnings
|
|
#--replace_result MyISAM <curr_engine> InnoDB <curr_engine>
|
|
#SHOW CREATE TABLE t1;
|
|
#INSERT INTO t1 VALUES ('2001-02-03 04:05:06');
|
|
#--sorted_result
|
|
#SELECT * FROM t1;
|
|
#SELECT a, hex(weight_string(a)) FROM t1;
|
|
#ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
|
|
#--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
|
|
#ALTER TABLE t1
|
|
#PARTITION BY RANGE (TO_DAYS(a))
|
|
#(PARTITION p0 VALUES LESS THAN (10000),
|
|
# PARTITION p1 VALUES LESS THAN (MAXVALUE));
|
|
#SHOW CREATE TABLE t1;
|
|
#CREATE TABLE t2 LIKE t1;
|
|
#SHOW CREATE TABLE t2;
|
|
#DROP TABLE t2;
|
|
#CREATE TABLE t2 SELECT * FROM t1;
|
|
#DROP TABLE t2;
|
|
#ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a));
|
|
#SHOW CREATE TABLE t1;
|
|
#ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
|
|
#SHOW CREATE TABLE t1;
|
|
#--sorted_result
|
|
#SELECT * FROM t1;
|
|
#DROP TABLE t1;
|
|
|
|
--echo #
|
|
--echo # Bug#31931: Mix of handlers error message
|
|
--echo #
|
|
--error ER_MIX_HANDLER_ERROR
|
|
CREATE TABLE t1 (a INT)
|
|
PARTITION BY HASH (a)
|
|
( PARTITION p0 ENGINE=MyISAM,
|
|
PARTITION p1);
|
|
--error ER_MIX_HANDLER_ERROR
|
|
CREATE TABLE t1 (a INT)
|
|
PARTITION BY LIST (a)
|
|
SUBPARTITION BY HASH (a)
|
|
( PARTITION p0 VALUES IN (0)
|
|
( SUBPARTITION s0, SUBPARTITION s1 ENGINE=MyISAM, SUBPARTITION s2),
|
|
PARTITION p1 VALUES IN (1)
|
|
( SUBPARTITION s3 ENGINE=MyISAM, SUBPARTITION s4, SUBPARTITION s5 ENGINE=MyISAM));
|
|
|
|
--echo #
|
|
--echo # Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
|
|
--echo #
|
|
CREATE TABLE t1 (a INT)
|
|
ENGINE = MyISAM
|
|
PARTITION BY HASH (a);
|
|
FLUSH TABLES;
|
|
--remove_file $MYSQLD_DATADIR/test/t1.par
|
|
--replace_result $MYSQLD_DATADIR ./
|
|
CHECK TABLE t1;
|
|
--error ER_FAILED_READ_FROM_PAR_FILE
|
|
SELECT * FROM t1;
|
|
--replace_result $MYSQLD_DATADIR ./
|
|
DROP TABLE t1;
|
|
--remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI
|
|
--remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYD
|
|
|
|
--echo #
|
|
--echo # Bug#50392: insert_id is not reset for partitioned tables
|
|
--echo # auto_increment on duplicate entry
|
|
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY)
|
|
ENGINE = MyISAM;
|
|
SET INSERT_ID= 13;
|
|
INSERT INTO t1 VALUES (NULL);
|
|
SET INSERT_ID= 12;
|
|
--echo # For transactional engines, 12 will not be inserted, since the failing
|
|
--echo # statement is rolled back.
|
|
--error ER_DUP_ENTRY
|
|
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
|
SHOW CREATE TABLE t1;
|
|
INSERT INTO t1 VALUES (NULL);
|
|
--echo # NOTE: 12 exists only in non transactional engines!
|
|
SELECT * FROM t1;
|
|
DROP TABLE t1;
|
|
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY)
|
|
ENGINE = MyISAM
|
|
PARTITION BY KEY(a);
|
|
SET INSERT_ID= 13;
|
|
INSERT INTO t1 VALUES (NULL);
|
|
SET INSERT_ID= 12;
|
|
--error ER_DUP_ENTRY
|
|
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
|
SHOW CREATE TABLE t1;
|
|
INSERT INTO t1 VALUES (NULL);
|
|
SELECT * FROM t1;
|
|
DROP TABLE t1;
|
|
#
|
|
# Bug#30102: rename table does corrupt tables with partition files on failure
|
|
#
|
|
--echo # Bug#30102 test
|
|
CREATE TABLE t1 (a INT)
|
|
ENGINE = MyISAM
|
|
PARTITION BY RANGE (a)
|
|
(PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION `p1....................` VALUES LESS THAN (9),
|
|
PARTITION p2 VALUES LESS THAN MAXVALUE);
|
|
# partition p1 is 't1#P#p1' + @002e * 20 = 107 characters + file ending
|
|
# total path lenght of './test/t1#P#p1@002e@002e<...>@002e.MY[ID]' is 118 chars
|
|
--echo # List of files in database `test`, all original t1-files here
|
|
--list_files $MYSQLD_DATADIR/test t1*
|
|
INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
|
--echo # Renaming to a file name where the first partition is 250 chars
|
|
--echo # and the second partition is 350 chars
|
|
# 7,7 avoids the error message, which is not deterministic.
|
|
--error 7,7
|
|
RENAME TABLE t1 TO `t2_new..............................................end`;
|
|
# 1234567890123456789012345678901234567890123456
|
|
--echo # List of files in database `test`, should not be any t2-files here
|
|
--list_files $MYSQLD_DATADIR/test t2*
|
|
--echo # List of files in database `test`, should be all t1-files here
|
|
--list_files $MYSQLD_DATADIR/test t1*
|
|
--sorted_result
|
|
SELECT * FROM t1;
|
|
--echo # List of files in database `test`, should be all t1-files here
|
|
--list_files $MYSQLD_DATADIR/test t1*
|
|
--echo # Renaming to a file name where the first partition is 156 chars
|
|
--echo # and the second partition is 256 chars
|
|
# 7,7 avoids the error message, which is not deterministic.
|
|
--error 7,7
|
|
RENAME TABLE t1 TO `t2_............................_end`;
|
|
# 1234567890123456789012345678
|
|
# 7 + 4 + 5 + 28 * 5 = 16 + 140 = 156
|
|
--echo # List of files in database `test`, should not be any t2-files here
|
|
--list_files $MYSQLD_DATADIR/test t2*
|
|
--echo # List of files in database `test`, should be all t1-files here
|
|
--list_files $MYSQLD_DATADIR/test t1*
|
|
--sorted_result
|
|
SELECT * FROM t1;
|
|
DROP TABLE t1;
|
|
--echo # Should not be any files left here
|
|
--list_files $MYSQLD_DATADIR/test t1*
|
|
--list_files $MYSQLD_DATADIR/test t2*
|
|
--echo # End of bug#30102 test.
|
|
|
|
--echo # Test of post-push fix for bug#11766249/59316
|
|
CREATE TABLE t1 (a INT, b VARCHAR(255), PRIMARY KEY (a))
|
|
ENGINE = MyISAM
|
|
PARTITION BY RANGE (a)
|
|
(PARTITION p0 VALUES LESS THAN (0) MAX_ROWS=100,
|
|
PARTITION p1 VALUES LESS THAN (100) MAX_ROWS=100,
|
|
PARTITION pMax VALUES LESS THAN MAXVALUE);
|
|
INSERT INTO t1 VALUES (1, "Partition p1, first row");
|
|
DROP TABLE t1;
|
|
|
|
--echo #
|
|
--echo # MDEV-10418 Assertion `m_extra_cache' failed
|
|
--echo # in ha_partition::late_extra_cache(uint)
|
|
--echo #
|
|
|
|
CREATE TABLE t1 (f1 INT) ENGINE=MyISAM;
|
|
INSERT INTO t1 VALUES (1),(2);
|
|
|
|
CREATE TABLE t2 (f2 INT) ENGINE=MyISAM PARTITION BY RANGE(f2) (PARTITION pmax VALUES LESS THAN MAXVALUE);
|
|
INSERT INTO t2 VALUES (8);
|
|
|
|
CREATE ALGORITHM = MERGE VIEW v AS SELECT f2 FROM t2, t1;
|
|
|
|
UPDATE v SET f2 = 1;
|
|
|
|
SELECT * FROM t2;
|
|
|
|
DROP VIEW v;
|
|
DROP TABLE t2;
|
|
DROP TABLE t1;
|
|
|
|
--echo #
|
|
--echo # bug#11760213-52599: ALTER TABLE REMOVE PARTITIONING ON NON-PARTITIONED
|
|
--echo # TABLE CORRUPTS MYISAM
|
|
--disable_warnings
|
|
DROP TABLE if exists `t1`;
|
|
--enable_warnings
|
|
CREATE TABLE `t1`(`a` INT)ENGINE=myisam;
|
|
ALTER TABLE `t1` ADD COLUMN `b` INT;
|
|
CREATE UNIQUE INDEX `i1` ON `t1`(`b`);
|
|
CREATE UNIQUE INDEX `i2` ON `t1`(`a`);
|
|
ALTER TABLE `t1` ADD PRIMARY KEY (`a`);
|
|
--error ER_PARTITION_MGMT_ON_NONPARTITIONED
|
|
ALTER TABLE `t1` REMOVE PARTITIONING;
|
|
CHECK TABLE `t1` EXTENDED;
|
|
DROP TABLE t1;
|
|
|
|
--echo #
|
|
--echo # MDEV-31122 Server crash in get_lock_data / mysql_lock_abort_for_thread
|
|
--echo #
|
|
CREATE TABLE t1 (a INT);
|
|
|
|
CREATE TABLE t2 (b INT, c varchar(5))
|
|
PARTITION BY RANGE COLUMNS(c)
|
|
SUBPARTITION by key(b) SUBPARTITIONS 2 (
|
|
PARTITION p0 VALUES LESS THAN ('m'),
|
|
PARTITION p1 VALUES LESS THAN ('z')
|
|
);
|
|
|
|
--connect (con1,localhost,root,,)
|
|
HANDLER t1 OPEN;
|
|
--send
|
|
SELECT b FROM t2 PARTITION (p0);
|
|
|
|
--connection default
|
|
SET lock_wait_timeout= 1;
|
|
--error 0,ER_STATEMENT_TIMEOUT,ER_LOCK_WAIT_TIMEOUT
|
|
ALTER TABLE t1 FORCE;
|
|
|
|
--connection con1
|
|
--reap
|
|
--disconnect con1
|
|
--connection default
|
|
DROP TABLE t2, t1;
|