maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #00390
bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (sanja:2712) Bug#41098
#At lp:maria
2712 sanja@xxxxxxxxxxxx 2009-06-11
Real fix for bug Bug#41098 (http://bugs.mysql.com/bug.php?id=41098). Invalidate tables changed in insert after unlocking tables when the result of insert become really visible.
modified:
sql/handler.h
sql/mysql_priv.h
sql/sql_base.cc
sql/sql_cache.cc
sql/sql_cache.h
sql/sql_delete.cc
sql/sql_insert.cc
sql/sql_load.cc
sql/sql_parse.cc
sql/sql_partition.cc
sql/sql_rename.cc
sql/sql_table.cc
sql/sql_update.cc
sql/sql_view.cc
sql/table.h
storage/maria/ha_maria.h
storage/myisam/ha_myisam.h
per-file messages:
sql/handler.h
table type for nontransactional tables with delayed to unlock insert visibility.
sql/mysql_priv.h
Invalidate call changed.
sql/sql_base.cc
Invalidation of marked tables.
sql/sql_cache.cc
Marking tables for on-unlock-invalidation added.
sql/sql_cache.h
Invalidate call changed.
sql/sql_delete.cc
Invalidate call changed.
sql/sql_insert.cc
Invalidate call changed.
sql/sql_load.cc
Invalidate call changed.
sql/sql_parse.cc
Invalidate call changed.
sql/sql_partition.cc
Invalidate call changed.
sql/sql_rename.cc
Invalidate call changed.
sql/sql_table.cc
Invalidate call changed.
sql/sql_update.cc
Invalidate call changed.
sql/sql_view.cc
Invalidate call changed.
sql/table.h
mark for tables which need query cache invalidation on unlock.
storage/maria/ha_maria.h
MyISAM and maria 1.5 use the new type of table for query cache.
storage/myisam/ha_myisam.h
MyISAM and maria 1.5 use the new type of table for query cache.
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2009-02-19 09:01:25 +0000
+++ b/sql/handler.h 2009-06-11 12:45:53 +0000
@@ -247,6 +247,11 @@
#define HA_CACHE_TBL_NOCACHE 1
#define HA_CACHE_TBL_ASKTRANSACT 2
#define HA_CACHE_TBL_TRANSACT 4
+/**
+ Non transactional table but insert results visible for other threads
+ only on unlock
+*/
+#define HA_CACHE_TBL_NTRNS_INS2LOCK 8
/* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */
#define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2009-04-25 10:05:32 +0000
+++ b/sql/mysql_priv.h 2009-06-11 12:45:53 +0000
@@ -893,7 +893,7 @@ struct Query_cache_query_flags
#define query_cache_init() query_cache.init()
#define query_cache_resize(A) query_cache.resize(A)
#define query_cache_set_min_res_unit(A) query_cache.set_min_res_unit(A)
-#define query_cache_invalidate3(A, B, C) query_cache.invalidate(A, B, C)
+#define query_cache_invalidate4(A, B, C, D) query_cache.invalidate(A, B, C, D)
#define query_cache_invalidate1(A) query_cache.invalidate(A)
#define query_cache_send_result_to_client(A, B, C) \
query_cache.send_result_to_client(A, B, C)
@@ -912,7 +912,7 @@ struct Query_cache_query_flags
#define query_cache_init()
#define query_cache_resize(A)
#define query_cache_set_min_res_unit(A)
-#define query_cache_invalidate3(A, B, C)
+#define query_cache_invalidate4(A, B, C, D)
#define query_cache_invalidate1(A)
#define query_cache_send_result_to_client(A, B, C) 0
#define query_cache_invalidate_by_MyISAM_filename_ref NULL
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2009-05-19 09:28:05 +0000
+++ b/sql/sql_base.cc 2009-06-11 12:45:53 +0000
@@ -1373,6 +1373,15 @@ bool close_thread_table(THD *thd, TABLE
table->s->table_name.str, (long) table));
*table_ptr=table->next;
+
+ /* Invalidate if it has mark about changing in insert
+ (not all tables has such marks */
+ if (table->changed_in_insert)
+ {
+ table->changed_in_insert= FALSE;
+ query_cache_invalidate4(thd, table, FALSE, FALSE);
+ }
+
/*
When closing a MERGE parent or child table, detach the children first.
Clear child table references to force new assignment at next open.
=== modified file 'sql/sql_cache.cc'
--- a/sql/sql_cache.cc 2009-04-25 10:05:32 +0000
+++ b/sql/sql_cache.cc 2009-06-11 12:45:53 +0000
@@ -1542,12 +1542,19 @@ err:
}
-/*
+/**
Remove all cached queries that uses any of the tables in the list
+
+ @param thd Thread handler
+ @param tables_used List of tables used in this operation
+ @param using_transactions Not in autocommit mode
+ @param insert It is insert operation
+
*/
void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
- my_bool using_transactions)
+ my_bool using_transactions,
+ my_bool insert)
{
DBUG_ENTER("Query_cache::invalidate (table list)");
@@ -1567,6 +1574,15 @@ void Query_cache::invalidate(THD *thd, T
force transaction finish.
*/
thd->add_changed_table(tables_used->table);
+ else if (insert &&
+ (tables_used->table->file->table_cache_type() ==
+ HA_CACHE_TBL_NTRNS_INS2LOCK))
+ {
+ /* for other threads */
+ tables_used->table->changed_in_insert= TRUE;
+ /* for this thread */
+ invalidate_table(thd, tables_used);
+ }
else
invalidate_table(thd, tables_used);
}
@@ -1619,12 +1635,18 @@ void Query_cache::invalidate_locked_for_
DBUG_VOID_RETURN;
}
-/*
+/**
Remove all cached queries that uses the given table
+
+ @param thd Thread handler
+ @param table TABLE descriptor
+ @param using_transactions Not in autocommit mode
+ @param insert It is insert operation
*/
-void Query_cache::invalidate(THD *thd, TABLE *table,
- my_bool using_transactions)
+void Query_cache::invalidate(THD *thd, TABLE *table,
+ my_bool using_transactions,
+ my_bool insert)
{
DBUG_ENTER("Query_cache::invalidate (table)");
@@ -1633,13 +1655,22 @@ void Query_cache::invalidate(THD *thd, T
if (using_transactions &&
(table->file->table_cache_type() == HA_CACHE_TBL_TRANSACT))
thd->add_changed_table(table);
+ else if (insert &&
+ (table->file->table_cache_type() ==
+ HA_CACHE_TBL_NTRNS_INS2LOCK))
+ {
+ /* for other threads */
+ table->changed_in_insert= TRUE;
+ /* for this thread */
+ invalidate_table(thd, table);
+ }
else
invalidate_table(thd, table);
-
DBUG_VOID_RETURN;
}
+
void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
my_bool using_transactions)
{
=== modified file 'sql/sql_cache.h'
--- a/sql/sql_cache.h 2008-07-24 13:41:55 +0000
+++ b/sql/sql_cache.h 2009-06-11 12:45:53 +0000
@@ -445,10 +445,11 @@ protected:
/* Remove all queries that uses any of the listed following tables */
void invalidate(THD* thd, TABLE_LIST *tables_used,
- my_bool using_transactions);
+ my_bool using_transactions, my_bool insert);
void invalidate(CHANGED_TABLE_LIST *tables_used);
void invalidate_locked_for_write(TABLE_LIST *tables_used);
- void invalidate(THD* thd, TABLE *table, my_bool using_transactions);
+ void invalidate(THD* thd, TABLE *table,
+ my_bool using_transactions, my_bool insert);
void invalidate(THD *thd, const char *key, uint32 key_length,
my_bool using_transactions);
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2009-04-25 09:04:38 +0000
+++ b/sql/sql_delete.cc 2009-06-11 12:45:53 +0000
@@ -370,7 +370,7 @@ cleanup:
*/
if (deleted)
{
- query_cache_invalidate3(thd, table_list, 1);
+ query_cache_invalidate4(thd, table_list, TRUE, FALSE);
}
delete select;
@@ -783,7 +783,7 @@ void multi_delete::abort()
/* Something already deleted so we have to invalidate cache */
if (deleted)
- query_cache_invalidate3(thd, delete_tables, 1);
+ query_cache_invalidate4(thd, delete_tables, TRUE, FALSE);
/*
If rows from the first table only has been deleted and it is
@@ -933,7 +933,7 @@ bool multi_delete::send_eof()
*/
if (deleted)
{
- query_cache_invalidate3(thd, delete_tables, 1);
+ query_cache_invalidate4(thd, delete_tables, TRUE, FALSE);
}
if ((local_error == 0) || thd->transaction.stmt.modified_non_trans_table)
{
@@ -1074,7 +1074,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST
error= ha_create_table(thd, path, table_list->db, table_list->table_name,
&create_info, 1);
VOID(pthread_mutex_unlock(&LOCK_open));
- query_cache_invalidate3(thd, table_list, 0);
+ query_cache_invalidate4(thd, table_list, FALSE, FALSE);
end:
if (!dont_send_ok)
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2009-04-25 10:05:32 +0000
+++ b/sql/sql_insert.cc 2009-06-11 12:45:53 +0000
@@ -880,7 +880,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
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);
+ query_cache_invalidate4(thd, table_list, TRUE, TRUE);
}
if ((changed && error <= 0) ||
thd->transaction.stmt.modified_non_trans_table ||
@@ -2743,7 +2743,7 @@ bool Delayed_insert::handle_inserts(void
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
goto err;
}
- query_cache_invalidate3(&thd, table, 1);
+ query_cache_invalidate4(&thd, table, TRUE, TRUE);
if (thr_reschedule_write_lock(*thd.lock->locks))
{
/* This is not known to happen. */
@@ -2785,7 +2785,7 @@ bool Delayed_insert::handle_inserts(void
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
goto err;
}
- query_cache_invalidate3(&thd, table, 1);
+ query_cache_invalidate4(&thd, table, TRUE, TRUE);
pthread_mutex_lock(&mutex);
DBUG_RETURN(0);
@@ -3208,7 +3208,7 @@ bool select_insert::send_eof()
We must invalidate the table in the query cache before binlog writing
and ha_autocommit_or_rollback.
*/
- query_cache_invalidate3(thd, table, 1);
+ query_cache_invalidate4(thd, table, TRUE, TRUE);
if (thd->transaction.stmt.modified_non_trans_table)
thd->transaction.all.modified_non_trans_table= TRUE;
}
@@ -3299,7 +3299,7 @@ void select_insert::abort() {
if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
thd->transaction.all.modified_non_trans_table= TRUE;
if (changed)
- query_cache_invalidate3(thd, table, 1);
+ query_cache_invalidate4(thd, table, TRUE, TRUE);
}
DBUG_ASSERT(transactional_table || !changed ||
thd->transaction.stmt.modified_non_trans_table);
=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc 2009-05-19 09:28:05 +0000
+++ b/sql/sql_load.cc 2009-06-11 12:45:53 +0000
@@ -446,7 +446,7 @@ int mysql_load(THD *thd,sql_exchange *ex
We must invalidate the table in query cache before binlog writing and
ha_autocommit_...
*/
- query_cache_invalidate3(thd, table_list, 0);
+ query_cache_invalidate4(thd, table_list, FALSE, FALSE);
if (error)
{
if (read_file_from_client)
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2009-04-25 10:05:32 +0000
+++ b/sql/sql_parse.cc 2009-06-11 12:45:53 +0000
@@ -3211,7 +3211,7 @@ end_with_restore_list:
/* INSERT ... SELECT should invalidate only the very first table */
TABLE_LIST *save_table= first_table->next_local;
first_table->next_local= 0;
- query_cache_invalidate3(thd, first_table, 1);
+ query_cache_invalidate4(thd, first_table, TRUE, FALSE);
first_table->next_local= save_table;
}
delete sel_result;
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2009-02-15 10:58:34 +0000
+++ b/sql/sql_partition.cc 2009-06-11 12:45:53 +0000
@@ -4012,7 +4012,7 @@ static int fast_end_partition(THD *thd,
thd->proc_info="end";
if (!is_empty)
- query_cache_invalidate3(thd, table_list, 0);
+ query_cache_invalidate4(thd, table_list, FALSE, FALSE);
error= ha_autocommit_or_rollback(thd, 0);
if (end_active_trans(thd))
=== modified file 'sql/sql_rename.cc'
--- a/sql/sql_rename.cc 2008-02-19 12:45:21 +0000
+++ b/sql/sql_rename.cc 2009-06-11 12:45:53 +0000
@@ -182,7 +182,7 @@ bool mysql_rename_tables(THD *thd, TABLE
}
if (!error)
- query_cache_invalidate3(thd, table_list, 0);
+ query_cache_invalidate4(thd, table_list, FALSE, FALSE);
pthread_mutex_lock(&LOCK_open);
unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2009-06-02 09:58:27 +0000
+++ b/sql/sql_table.cc 2009-06-11 12:45:53 +0000
@@ -1775,7 +1775,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
if (some_tables_deleted || tmp_table_deleted || !error)
{
- query_cache_invalidate3(thd, tables, 0);
+ query_cache_invalidate4(thd, tables, FALSE, FALSE);
if (!dont_log_query)
{
if (!thd->current_stmt_binlog_row_based ||
@@ -4372,7 +4372,7 @@ static bool mysql_admin_table(THD* thd,
if (thd->killed)
goto err;
/* Flush entries in the query cache involving this table. */
- query_cache_invalidate3(thd, table->table, 0);
+ query_cache_invalidate4(thd, table->table, FALSE, FALSE);
open_for_modify= 0;
}
@@ -4628,7 +4628,7 @@ send_result_message:
pthread_mutex_unlock(&LOCK_open);
}
/* May be something modified consequently we have to invalidate cache */
- query_cache_invalidate3(thd, table->table, 0);
+ query_cache_invalidate4(thd, table->table, FALSE, FALSE);
}
}
ha_autocommit_or_rollback(thd, 0);
@@ -5163,7 +5163,7 @@ mysql_discard_or_import_tablespace(THD *
The 0 in the call below means 'not in a transaction', which means
immediate invalidation; that is probably what we wish here
*/
- query_cache_invalidate3(thd, table_list, 0);
+ query_cache_invalidate4(thd, table_list, FALSE, FALSE);
/* The ALTER TABLE is always in its own transaction */
error = ha_autocommit_or_rollback(thd, 0);
@@ -6433,7 +6433,7 @@ view_err:
unlink_open_table(thd, name_lock, FALSE);
VOID(pthread_mutex_unlock(&LOCK_open));
table_list->table= NULL; // For query cache
- query_cache_invalidate3(thd, table_list, 0);
+ query_cache_invalidate4(thd, table_list, FALSE, FALSE);
DBUG_RETURN(error);
}
@@ -7097,7 +7097,7 @@ view_err:
ha_flush_logs(old_db_type);
}
table_list->table=0; // For query cache
- query_cache_invalidate3(thd, table_list, 0);
+ query_cache_invalidate4(thd, table_list, FALSE, FALSE);
if (thd->locked_tables && (new_name != table_name || new_db != db))
{
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2009-04-25 09:04:38 +0000
+++ b/sql/sql_update.cc 2009-06-11 12:45:53 +0000
@@ -779,7 +779,7 @@ int mysql_update(THD *thd,
*/
if (updated)
{
- query_cache_invalidate3(thd, table_list, 1);
+ query_cache_invalidate4(thd, table_list, TRUE, FALSE);
}
/*
@@ -1780,7 +1780,7 @@ void multi_update::abort()
/* Something already updated so we have to invalidate cache */
if (updated)
- query_cache_invalidate3(thd, update_tables, 1);
+ query_cache_invalidate4(thd, update_tables, TRUE, FALSE);
/*
If all tables that has been updated are trans safe then just do rollback.
If not attempt to do remaining updates.
@@ -2023,7 +2023,7 @@ bool multi_update::send_eof()
if (updated)
{
- query_cache_invalidate3(thd, update_tables, 1);
+ query_cache_invalidate4(thd, update_tables, TRUE, FALSE);
}
/*
Write the SQL statement to the binlog if we updated
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2009-04-25 10:05:32 +0000
+++ b/sql/sql_view.cc 2009-06-11 12:45:53 +0000
@@ -667,7 +667,7 @@ bool mysql_create_view(THD *thd, TABLE_L
VOID(pthread_mutex_unlock(&LOCK_open));
if (mode != VIEW_CREATE_NEW)
- query_cache_invalidate3(thd, view, 0);
+ query_cache_invalidate4(thd, view, FALSE, FALSE);
start_waiting_global_read_lock(thd);
if (res)
goto err;
@@ -1631,7 +1631,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
pthread_mutex_unlock(&share->mutex);
release_table_share(share, RELEASE_WAIT_FOR_DROP);
}
- query_cache_invalidate3(thd, view, 0);
+ query_cache_invalidate4(thd, view, FALSE, FALSE);
sp_cache_invalidate();
}
@@ -1983,7 +1983,7 @@ mysql_rename_view(THD *thd,
DBUG_RETURN(1);
/* remove cache entries */
- query_cache_invalidate3(thd, view, 0);
+ query_cache_invalidate4(thd, view, FALSE, FALSE);
sp_cache_invalidate();
error= FALSE;
=== modified file 'sql/table.h'
--- a/sql/table.h 2009-02-19 09:01:25 +0000
+++ b/sql/table.h 2009-06-11 12:45:53 +0000
@@ -790,6 +790,7 @@ struct st_table {
my_bool get_fields_in_item_tree; /* Signal to fix_field */
/* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */
my_bool children_attached;
+ my_bool changed_in_insert; /* Have been changed in insert since last lock */
REGINFO reginfo; /* field connections */
MEM_ROOT mem_root;
=== modified file 'storage/maria/ha_maria.h'
--- a/storage/maria/ha_maria.h 2008-12-02 22:02:52 +0000
+++ b/storage/maria/ha_maria.h 2009-06-11 12:45:53 +0000
@@ -164,4 +164,6 @@ public:
return file;
}
static int implicit_commit(THD *thd, bool new_trn);
+ /** Type of table for caching query */
+ virtual uint8 table_cache_type() { return HA_CACHE_TBL_NTRNS_INS2LOCK; }
};
=== modified file 'storage/myisam/ha_myisam.h'
--- a/storage/myisam/ha_myisam.h 2008-06-28 12:45:15 +0000
+++ b/storage/myisam/ha_myisam.h 2009-06-11 12:45:53 +0000
@@ -147,4 +147,6 @@ class ha_myisam: public handler
{
return file;
}
+ /** Type of table for caching query */
+ virtual uint8 table_cache_type() { return HA_CACHE_TBL_NTRNS_INS2LOCK; }
};
Follow ups