diff --git a/KNOWN_BUGS.txt b/KNOWN_BUGS.txt index a69384910e2..12f9c2fa123 100644 --- a/KNOWN_BUGS.txt +++ b/KNOWN_BUGS.txt @@ -54,16 +54,7 @@ Known bugs that are planned to be fixed later ============================================= LOCK TABLES .. WRITE CONCURRENT is mainly done for testing MVCC. Don't -use this in production. Things that is not working if you are using -this on a table: - -- INSERT/REPLACE ... SELECT on an empty table may cause crashes or - wrong results if someone else is doing writes on the table during repair - or someone is doing selects during the repair index phase. - -INSERT ... SELECT, REPLACE ... SELECT and LOAD DATA are blocking -inserts and SELECT for the table. They should only have to do this if -the destination is empty (as then we are using fast index rebuild). +use this in production. Missing features that is planned to fix before Beta =================================================== diff --git a/mysql-test/r/maria-mvcc.result b/mysql-test/r/maria-mvcc.result index 0fec28697c2..3919dfc597e 100644 --- a/mysql-test/r/maria-mvcc.result +++ b/mysql-test/r/maria-mvcc.result @@ -6,70 +6,78 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) DEFAULT NULL ) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +insert into t1 values (0); lock tables t1 write concurrent; insert into t1 values (1); insert into t1 values (2); -/* should see 1 and 2 */ +/* should see 0, 1 and 2 */ select i from t1; i +0 1 2 select count(*) from t1; count(*) -2 -/* should see nothing */ +3 +/* should see 0 */ select i from t1; i +0 select count(*) from t1; count(*) -0 +1 lock tables t1 write concurrent; insert into t1 values (3); insert into t1 values (4); -/* should see 3 and 4 */ +/* should see 0, 3 and 4 */ select i from t1; i +0 3 4 select count(*) from t1; count(*) -2 +3 unlock tables; lock tables t1 write concurrent; insert into t1 values (5); -/* should see 3, 4 and 5 */ +/* should see 0, 3, 4 and 5 */ select i from t1; i +0 3 4 5 select count(*) from t1; count(*) -3 +4 lock tables t1 write concurrent; -/* should see 3, 4 */ +/* should see 0, 3, 4 */ select i from t1; i +0 3 4 select count(*) from t1; count(*) -2 +3 insert into t1 values (6); -/* Should see 1, 2, 6 */ +/* Should see 0, 1, 2, 6 */ select i from t1; i +0 1 2 6 select count(*) from t1; count(*) -3 +4 unlock tables; lock tables t1 write concurrent; -/* Should see 1, 2, 3, 4 and 6 */ +/* Should see 0, 1, 2, 3, 4 and 6 */ select i from t1; i +0 1 2 3 @@ -77,20 +85,22 @@ i 6 select count(*) from t1; count(*) -5 -/* should see 3, 4, 5 */ +6 +/* should see 0, 3, 4, 5 */ select i from t1; i +0 3 4 5 select count(*) from t1; count(*) -3 +4 unlock tables; -/* should see 1, 2, 3, 4, 5, 6 */ +/* should see 0, 1, 2, 3, 4, 5, 6 */ select i from t1; i +0 1 2 3 @@ -99,11 +109,12 @@ i 6 select count(*) from t1; count(*) -6 +7 unlock tables; -/* should see 1, 2, 3, 4, 5, 6 */ +/* should see 0, 1, 2, 3, 4, 5, 6 */ select i from t1; i +0 1 2 3 @@ -112,21 +123,23 @@ i 6 select count(*) from t1; count(*) -6 +7 insert into t1 values (7); -/* should see 3, 4, 7 */ +/* should see 0, 3, 4, 7 */ select i from t1; i +0 3 4 7 select count(*) from t1; count(*) -3 +4 unlock tables; -/* should see 1, 2, 3, 4, 5, 6, 7 */ +/* should see 0, 1, 2, 3, 4, 5, 6, 7 */ select i from t1; i +0 1 2 3 @@ -136,7 +149,7 @@ i 7 select count(*) from t1; count(*) -7 +8 drop table t1; CREATE TABLE t1 (fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, g GEOMETRY NOT NULL, SPATIAL KEY(g) ) transactional=1 row_format=page engine=maria; lock tables t1 write concurrent, t1 as t2 write concurrent; diff --git a/mysql-test/t/maria-mvcc.test b/mysql-test/t/maria-mvcc.test index f1ef9c34474..4b6f8a3996d 100644 --- a/mysql-test/t/maria-mvcc.test +++ b/mysql-test/t/maria-mvcc.test @@ -15,71 +15,75 @@ connection con1; create table t1 (i int) engine=maria; show create table t1; + +# versioning is disabled when table is empty, so insert a row +insert into t1 values (0); + lock tables t1 write concurrent; insert into t1 values (1); insert into t1 values (2); -/* should see 1 and 2 */ +/* should see 0, 1 and 2 */ select i from t1; select count(*) from t1; connect (con2,localhost,root,,); connection con2; -/* should see nothing */ +/* should see 0 */ select i from t1; select count(*) from t1; lock tables t1 write concurrent; insert into t1 values (3); insert into t1 values (4); -/* should see 3 and 4 */ +/* should see 0, 3 and 4 */ select i from t1; select count(*) from t1; unlock tables; lock tables t1 write concurrent; insert into t1 values (5); -/* should see 3, 4 and 5 */ +/* should see 0, 3, 4 and 5 */ select i from t1; select count(*) from t1; connect (con3,localhost,root,,); connection con3; lock tables t1 write concurrent; -/* should see 3, 4 */ +/* should see 0, 3, 4 */ select i from t1; select count(*) from t1; connection con1; insert into t1 values (6); -/* Should see 1, 2, 6 */ +/* Should see 0, 1, 2, 6 */ select i from t1; select count(*) from t1; unlock tables; lock tables t1 write concurrent; -/* Should see 1, 2, 3, 4 and 6 */ +/* Should see 0, 1, 2, 3, 4 and 6 */ select i from t1; select count(*) from t1; connection con2; -/* should see 3, 4, 5 */ +/* should see 0, 3, 4, 5 */ select i from t1; select count(*) from t1; unlock tables; -/* should see 1, 2, 3, 4, 5, 6 */ +/* should see 0, 1, 2, 3, 4, 5, 6 */ select i from t1; select count(*) from t1; connection con1; unlock tables; -/* should see 1, 2, 3, 4, 5, 6 */ +/* should see 0, 1, 2, 3, 4, 5, 6 */ select i from t1; select count(*) from t1; connection con3; insert into t1 values (7); -/* should see 3, 4, 7 */ +/* should see 0, 3, 4, 7 */ select i from t1; select count(*) from t1; unlock tables; -/* should see 1, 2, 3, 4, 5, 6, 7 */ +/* should see 0, 1, 2, 3, 4, 5, 6, 7 */ select i from t1; select count(*) from t1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7cc2c928521..cbb20bac3e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2154,6 +2154,7 @@ mysql_execute_command(THD *thd) goto error; #endif } + break; case SQLCOM_SHOW_NEW_MASTER: { if (check_global_access(thd, REPL_SLAVE_ACL)) diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 44f6d88279c..bbc9570dd8b 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1812,9 +1812,12 @@ void ha_maria::start_bulk_insert(ha_rows rows) a lot of rows. We should not do this for only a few rows as this is slower and we don't want to update the key statistics based of only a few rows. + Index file rebuild requires an exclusive lock, so if versioning is on + don't do it (see how ha_maria::store_lock() tries to predict repair). */ if (file->state->records == 0 && can_enable_indexes && - (!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES)) + (!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES) && + (file->lock.type == TL_WRITE)) { /** @todo for a single-row INSERT SELECT, we will go into repair, which @@ -2478,13 +2481,23 @@ THR_LOCK_DATA **ha_maria::store_lock(THD *thd, !thd->current_stmt_binlog_row_based && (thd->lex->sql_command != SQLCOM_SELECT && thd->lex->sql_command != SQLCOM_LOCK_TABLES) && + (thd->options & OPTION_BIN_LOG) && mysql_bin_log.is_open()) lock_type= TL_READ_NO_INSERT; else if (lock_type == TL_WRITE_CONCURRENT_INSERT && - (thd->lex->sql_command == SQLCOM_INSERT_SELECT || - thd->lex->sql_command == SQLCOM_REPLACE_SELECT || - thd->lex->sql_command == SQLCOM_LOAD)) + (file->state->records == 0)) + { + /* + Bulk insert may use repair, which will cause problems if other + threads try to read/insert to the table: disable versioning. + Note that our read of file->state->records is incorrect, as such + variable may have changed when we come to start_bulk_insert() (worse + case: we see != 0 so allow versioning, start_bulk_insert() sees 0 and + uses repair). This is prevented because start_bulk_insert() will not + try repair if we enabled versioning. + */ lock_type= TL_WRITE; + } file->lock.type= lock_type; } *to++= &file->lock; diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index d885d50a42f..e35b5eaac86 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -601,15 +601,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) pos->null_bit=0; pos->flag=0; /* For purify */ pos++; - - if ((share->keyinfo[i].flag & HA_NOSAME) && i != 0) - { - /* - We can't yet have versioning if there is more than one unique - key - */ - versioning= 0; - } } for (i=0 ; i < uniques ; i++) {