Bug #9686 | inconsistent update with selfreference via merge table | ||
---|---|---|---|
Submitted: | 6 Apr 2005 16:44 | Modified: | 3 Oct 2008 13:32 |
Reporter: | Martin Friebe (Gold Quality Contributor) (OCA) | Email Updates: | |
Status: | Can't repeat | Impact on me: | |
Category: | MySQL Server: Merge storage engine | Severity: | S3 (Non-critical) |
Version: | 4.1.15-BK | OS: | Linux (Linux) |
Assigned to: | CPU Architecture: | Any | |
Tags: | qc |
[6 Apr 2005 16:44]
Martin Friebe
[6 Apr 2005 16:51]
Martin Friebe
actually the bug goes even further, the example without rand() order should at least return the value "2" for all rows. ( max(1)+1 = 2 ) So I removed this beeing a "cache" error
[6 Apr 2005 17:44]
Martin Friebe
sorry, just seen after pasting and copying, I left an error in the 2nd set of sql' instead of update t1 set a = (select max(a)+1 from tm order ); it should be update t1 set a = (select max(a)+1 from tm ); setting all results to 2 However the behaviour is the same with set GLOBAL query_cache_limit=0 so it seems to be cached outside the query cache
[4 Oct 2005 13:29]
Mark Matthews
Reverify, please.
[5 Oct 2005 12:25]
Valeriy Kravchuk
The problem as originally reported is either a bug (I think) or a "feature" that should be described. Verified on latest 4.1.15-BK build: mysql> create table t1 (a int(11)) engine=MyISAM; Query OK, 0 rows affected (0.00 sec) mysql> create table t2 (a int(11)) engine=MRG_MyISAM UNION=(t1); Query OK, 0 rows affected (0.07 sec) mysql> insert into t1 values (1), (1), (1); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> update t1 set a = (select max(a)+1 from t2 order by rand()); Query OK, 3 rows affected (0.02 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql> select * from t1; +------+ | a | +------+ | 2 | | 3 | | 4 | +------+ 3 rows in set (0.00 sec) So, we have inconsistem results really. mysql> update t1 set a = 1; Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql> select * from t1; +------+ | a | +------+ | 1 | | 1 | | 1 | +------+ 3 rows in set (0.01 sec) mysql> update t1 set a = (select max(a)+1 from t1 order by rand()); ERROR 1093 (HY000): You can't specify target table 't1' for update in FROM clause Because of MERGE table usage (and what about views in 5.0.x?)... This query, from the later comment: mysql> update t1 set a = (select max(a)+1 from t2); Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql> select * from t1; +------+ | a | +------+ | 2 | | 2 | | 2 | +------+ 3 rows in set (0.00 sec) give consistent result really. Yes, there was a cache: mysql> show variables like 'query_cache%'; +------------------------------+---------+ | Variable_name | Value | +------------------------------+---------+ | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 0 | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | +------------------------------+---------+ 5 rows in set (0.01 sec) But it does not metter: mysql> set GLOBAL query_cache_limit=0; Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'query_cache%'; +------------------------------+-------+ | Variable_name | Value | +------------------------------+-------+ | query_cache_limit | 0 | | query_cache_min_res_unit | 4096 | | query_cache_size | 0 | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | +------------------------------+-------+ 5 rows in set (0.00 sec) mysql> update t1 set a = 1; Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql> update t1 set a = (select max(a)+1 from t1 order by rand()); ERROR 1093 (HY000): You can't specify target table 't1' for update in FROM clause mysql> update t1 set a = (select max(a)+1 from t2 order by rand()); Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql> select * from t1; +------+ | a | +------+ | 2 | | 3 | | 4 | +------+ 3 rows in set (0.00 sec) mysql> select version(); +--------------+ | version() | +--------------+ | 4.1.15-debug | +--------------+ 1 row in set (0.00 sec)
[18 Oct 2005 10:31]
Ingo Strüwing
I guess this one will be fixed (in the sense of Martins proposal no. 1) when I fix Bug #5390.
[27 Apr 2006 16:55]
Ingo Strüwing
Unfortunately, it's not. The bug still exists in 4.1.19. Bug#5390 was fixed in 4.1.17.
[12 Jul 2006 18:05]
Antony Curtis
I think this is working as designed. There is no way for mysqld to know the dependencies between the MyISAMMRG table and the MyISAM table - as far as mysqld is concerned, they are logically two independent tables. The optimiser will examine subselects to see if they may be replaced with a fixed constant. In this case, the statement "SELECT max(a)+1 FROM t1" is seen as a deterministic statement which may be optimized by being replaced with a constant. Appending to the subselect a "ORDER BY RAND()" is a simple/effective (and probably documented somewhere) method to prevent the optimiser form replacing the subselect with a constant. Therefore, the two UPDATE statements will have a different result because of how one table is working as an alias for the other. I would imagine that this same behaviour is possible without having to use MyISAMMRG: Start mysqld with external locking enabled, create two MyISAM tables with the same row format, hard link one tables MYD file to the other.
[29 Sep 2006 14:56]
Igor Babaev
I don't believe this is a kind of bug that is to be fixed for 5.1. The fix would require introduction of new handler functions such as get_first_underlying_table and get_net_underlying_table. In other words the fix would require new architectural features. At the same time I think the problem should be fixed in future versions for sure.
[29 Sep 2008 21:42]
Konstantin Osipov
We fixed a number of merge table issues in 5.1 and 6.0. The bug needs to be re-verified.
[3 Oct 2008 13:32]
Valeriy Kravchuk
Not repeatable any more with 5.0.66a, 5.1.28 and 6.0.6: C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -uroot -proot -P3310 test Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 5.1.28-rc-community MySQL Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> drop table t1; Query OK, 0 rows affected (0.03 sec) mysql> drop table t2; Query OK, 0 rows affected (0.03 sec) mysql> create table t1 (a int(11)) engine=MyISAM; Query OK, 0 rows affected (0.08 sec) mysql> create table t2 (a int(11)) engine=MRG_MyISAM UNION=(t1); Query OK, 0 rows affected (0.09 sec) mysql> insert into t1 values (1), (1), (1); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> update t1 set a = (select max(a)+1 from t2 order by rand()); ERROR 1093 (HY000): You can't specify target table 't1' for update in FROM claus e mysql> update t1 set a = (select max(a)+1 from t1 order by rand()); ERROR 1093 (HY000): You can't specify target table 't1' for update in FROM claus e