Below is the list of changes that have just been committed into a local
5.0 repository of bell. When bell does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2085 06/03/15 19:15:52 bell@stripped +5 -0
We should prohobit concurent read of inserting file in SP
because it can couse problem with Query cache (BUG#14767)
sql/sql_yacc.yy
1.462 06/03/15 19:15:43 bell@stripped +23 -2
We should prohibit concurent read of unserting file in SP
because it can cause problem with query cache.
sql/sql_parse.cc
1.536 06/03/15 19:15:42 bell@stripped +13 -0
Query cache invalidation table we was inserting in just after
unlocking table added to avoid the race condition as we had
with SP.
sql/sql_insert.cc
1.184 06/03/15 19:15:42 bell@stripped +30 -21
Query cache invalidation table we was inserting in just after
unlocking table added to avoid the race condition as we had
with SP.
mysql-test/t/query_cache_notembedded.test
1.4 06/03/15 19:15:42 bell@stripped +40 -0
BUG#14767 test suite.
mysql-test/r/query_cache_notembedded.result
1.4 06/03/15 19:15:41 bell@stripped +30 -0
BUG#14767 test suite.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: bell
# Host: book.local
# Root: /Users/bell/mysql/bk/work-qc-5.0
--- 1.183/sql/sql_insert.cc 2006-01-06 18:36:10 +02:00
+++ 1.184/sql/sql_insert.cc 2006-03-15 19:15:42 +02:00
@@ -258,6 +258,7 @@
bool log_on= (thd->options & OPTION_BIN_LOG) ||
(!(thd->security_ctx->master_access & SUPER_ACL));
bool transactional_table, joins_freed= FALSE;
+ bool changed;
uint value_count;
ulong counter = 1;
ulonglong id;
@@ -544,32 +545,30 @@
else if (table->next_number_field && info.copied)
id=table->next_number_field->val_int(); // Return auto_increment value
- /*
- Invalidate the table in the query cache if something changed.
- For the transactional algorithm to work the invalidation must be
- before binlog writing and ha_autocommit_or_rollback
- */
- if (info.copied || info.deleted || info.updated)
- {
- query_cache_invalidate3(thd, table_list, 1);
- }
-
transactional_table= table->file->has_transactions();
- if ((info.copied || info.deleted || info.updated) &&
- (error <= 0 || !transactional_table))
+ if ((changed= (info.copied || info.deleted || info.updated)))
{
- if (mysql_bin_log.is_open())
+ /*
+ Invalidate the table in the query cache if something changed.
+ For the transactional algorithm to work the invalidation must be
+ before binlog writing and ha_autocommit_or_rollback
+ */
+ query_cache_invalidate3(thd, table_list, 1);
+ if (error <= 0 || !transactional_table)
{
- if (error <= 0)
- thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE);
- if (mysql_bin_log.write(&qinfo) && transactional_table)
- error=1;
+ if (mysql_bin_log.is_open())
+ {
+ if (error <= 0)
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ transactional_table, FALSE);
+ if (mysql_bin_log.write(&qinfo) && transactional_table)
+ error=1;
+ }
+ if (!transactional_table)
+ thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (!transactional_table)
- thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
if (transactional_table)
error=ha_autocommit_or_rollback(thd,error);
@@ -577,6 +576,16 @@
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
+ /*
+ Invalidate the table in the query cache if something changed
+ after unlocking when changes become fisible.
+ TODO: this is workaround. right way will be move invalidating in
+ the unlock procedure.
+ */
+ if (lock_type == TL_WRITE_CONCURRENT_INSERT && changed)
+ {
+ query_cache_invalidate3(thd, table_list, 1);
+ }
thd->lock=0;
}
}
--- 1.535/sql/sql_parse.cc 2006-03-10 13:40:12 +02:00
+++ 1.536/sql/sql_parse.cc 2006-03-15 19:15:42 +02:00
@@ -3314,6 +3314,19 @@
select_lex->context.table_list=
select_lex->context.first_name_resolution_table= second_table;
res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
+ /*
+ Invalidate the table in the query cache if something changed
+ after unlocking when changes become visible.
+ TODO: this is workaround. right way will be move invalidating in
+ the unlock procedure.
+ */
+ if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
+ thd->lock)
+ {
+ mysql_unlock_tables(thd, thd->lock);
+ query_cache_invalidate3(thd, first_table, 1);
+ thd->lock=0;
+ }
delete result;
}
/* revert changes for SP */
--- 1.461/sql/sql_yacc.yy 2006-03-10 16:47:43 +02:00
+++ 1.462/sql/sql_yacc.yy 2006-03-15 19:15:43 +02:00
@@ -6068,7 +6068,19 @@
;
insert_lock_option:
- /* empty */ { $$= TL_WRITE_CONCURRENT_INSERT; }
+ /* empty */
+ {
+#ifdef HAVE_QUERY_CACHE
+ /*
+ If it is SP we do not allow insert optimisation whan result of
+ insert visible only after the table unlocking but everyone can
+ read table.
+ */
+ $$= (Lex->sphead ? TL_WRITE :TL_WRITE_CONCURRENT_INSERT);
+#else
+ $$= TL_WRITE_CONCURRENT_INSERT;
+#endif
+ }
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
| DELAYED_SYM { $$= TL_WRITE_DELAYED; }
| HIGH_PRIORITY { $$= TL_WRITE; }
@@ -6925,7 +6937,16 @@
load_data_lock:
/* empty */ { $$= YYTHD->update_lock_default; }
- | CONCURRENT { $$= TL_WRITE_CONCURRENT_INSERT ; }
+ | CONCURRENT
+ {
+#ifdef HAVE_QUERY_CACHE
+ /*
+ Ignore this option in SP to avoid problem with query cache
+ */
+ if (Lex->sphead != 0)
+#endif
+ $$= TL_WRITE_CONCURRENT_INSERT;
+ }
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; };
--- 1.3/mysql-test/r/query_cache_notembedded.result 2006-02-24 18:34:08 +02:00
+++ 1.4/mysql-test/r/query_cache_notembedded.result 2006-03-15 19:15:41 +02:00
@@ -314,4 +314,34 @@
drop procedure f3;
drop procedure f4;
drop table t1;
+reset query cache;
+drop function if exists f1;
+create table t1 (id int);
+create function f1 ()
+returns int
+begin
+declare i_var int;
+set i_var = sleep(3);
+insert into t1 values(3);
+set i_var = sleep(3);
+return 0;
+end;|
+ select f1();
+select sleep(4);
+sleep(4)
+0
+select * from t1;
+id
+3
+f1()
+0
+select * from t1;
+id
+3
+reset query cache;
+select * from t1;
+id
+3
+drop table t1;
+drop function f1;
set GLOBAL query_cache_size=0;
--- 1.3/mysql-test/t/query_cache_notembedded.test 2006-02-24 18:34:08 +02:00
+++ 1.4/mysql-test/t/query_cache_notembedded.test 2006-03-15 19:15:42 +02:00
@@ -180,5 +180,45 @@
drop procedure f4;
drop table t1;
+#
+# bug#14767: INSERT in SF + concurrent SELECT with query cache
+#
+reset query cache;
+--disable_warnings
+drop function if exists f1;
+--enable_warnings
+create table t1 (id int);
+delimiter |;
+create function f1 ()
+ returns int
+begin
+ declare i_var int;
+ set i_var = sleep(3);
+ insert into t1 values(3);
+ set i_var = sleep(3);
+ return 0;
+end;|
+delimiter ;|
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+send select f1();
+connection con2;
+select sleep(4);
+select * from t1;
+connection con1;
+reap;
+connection con2;
+# This gives wrong result i.e. 't' table seems to be empty
+select * from t1;
+reset query cache;
+select * from t1;
+drop table t1;
+drop function f1;
+disconnect con1;
+disconnect con2;
+connection default;
set GLOBAL query_cache_size=0;
| Thread |
|---|
| • bk commit into 5.0 tree (bell:1.2085) BUG#14767 | sanja | 15 Mar |