summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorDaniele Sciascia <daniele.sciascia@galeracluster.com>2015-10-20 17:54:14 +0200
committerNirbhay Choubey <nirbhay@mariadb.com>2016-02-22 17:46:22 -0500
commitace86a2375c3f47badf49796eda14959b0487269 (patch)
tree2287be909e31bbdd9ed914f3065d646b3ace6122 /sql
parentc1ea0570af88ed12f55fc20c54262b3688b9981d (diff)
downloadmariadb-git-ace86a2375c3f47badf49796eda14959b0487269.tar.gz
refs codership/mysql-wsrep#201
- Fixes query cache so that it is aware of wsrep_sync_wait. Query cache would return (possibly stale) results to the client, regardless of the value of wsrep_sync_wait. - Includes the test case that reproduced the issue.
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_cache.cc20
-rw-r--r--sql/sql_class.cc6
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/wsrep_mysqld.cc17
-rw-r--r--sql/wsrep_mysqld.h1
5 files changed, 39 insertions, 7 deletions
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index e1efb1e85d6..0d3497ad964 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1846,6 +1846,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
goto err;
}
}
+
/*
Try to obtain an exclusive lock on the query cache. If the cache is
disabled or if a full cache flush is in progress, the attempt to
@@ -1957,6 +1958,25 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
}
DBUG_PRINT("qcache", ("Query in query hash 0x%lx", (ulong)query_block));
+#ifdef WITH_WSREP
+ if (WSREP_CLIENT(thd) && wsrep_must_sync_wait(thd)) {
+ unlock();
+ if (wsrep_sync_wait(thd))
+ goto err;
+ if (try_lock(TRUE))
+ goto err;
+ query_block = (Query_cache_block *) my_hash_search(&queries,
+ (uchar*) sql,
+ tot_length);
+ if (query_block == 0 ||
+ query_block->query()->result() == 0 ||
+ query_block->query()->result()->type != Query_cache_block::RESULT)
+ {
+ goto err_unlock;
+ }
+ }
+#endif /* WITH_WSREP */
+
/* Now lock and test that nothing changed while blocks was unlocked */
BLOCK_LOCK_RD(query_block);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 7705ac45ffa..fa26494f35b 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1213,6 +1213,7 @@ THD::THD()
wsrep_mysql_replicated = 0;
wsrep_TOI_pre_query = NULL;
wsrep_TOI_pre_query_len = 0;
+ wsrep_sync_wait_gtid= WSREP_GTID_UNDEFINED;
#endif
/* Call to init() below requires fully initialized Open_tables_state. */
reset_open_tables_state(this);
@@ -1628,6 +1629,7 @@ void THD::init(void)
wsrep_mysql_replicated = 0;
wsrep_TOI_pre_query = NULL;
wsrep_TOI_pre_query_len = 0;
+ wsrep_sync_wait_gtid= WSREP_GTID_UNDEFINED;
/*
@@wsrep_causal_reads is now being handled via wsrep_sync_wait, update it
@@ -2361,6 +2363,10 @@ void THD::cleanup_after_query()
rgi_slave->cleanup_after_query();
#endif
+#ifdef WITH_WSREP
+ wsrep_sync_wait_gtid= WSREP_GTID_UNDEFINED;
+#endif /* WITH_WSREP */
+
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 431edc3b38c..aee4d1dc359 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2787,7 +2787,6 @@ public:
query_id_t first_query_id;
} binlog_evt_union;
-
/**
Internal parser state.
Note that since the parser is not re-entrant, we keep only one parser
@@ -3865,6 +3864,7 @@ public:
void* wsrep_apply_format;
bool wsrep_apply_toi; /* applier processing in TOI */
bool wsrep_skip_append_keys;
+ wsrep_gtid_t wsrep_sync_wait_gtid;
#endif /* WITH_WSREP */
};
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index e622389de7e..0dd5c4dba14 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -810,19 +810,24 @@ bool wsrep_start_replication()
return true;
}
+bool wsrep_must_sync_wait (THD* thd, uint mask)
+{
+ return (thd->variables.wsrep_sync_wait & mask) &&
+ thd->variables.wsrep_on &&
+ !thd->in_active_multi_stmt_transaction() &&
+ thd->wsrep_conflict_state != REPLAYING &&
+ thd->wsrep_sync_wait_gtid.seqno == WSREP_SEQNO_UNDEFINED;
+}
+
bool wsrep_sync_wait (THD* thd, uint mask)
{
- if ((thd->variables.wsrep_sync_wait & mask) &&
- thd->variables.wsrep_on &&
- !thd->in_active_multi_stmt_transaction() &&
- thd->wsrep_conflict_state != REPLAYING)
+ if (wsrep_must_sync_wait(thd, mask))
{
WSREP_DEBUG("wsrep_sync_wait: thd->variables.wsrep_sync_wait = %u, mask = %u",
thd->variables.wsrep_sync_wait, mask);
// This allows autocommit SELECTs and a first SELECT after SET AUTOCOMMIT=0
// TODO: modify to check if thd has locked any rows.
- wsrep_gtid_t gtid;
- wsrep_status_t ret= wsrep->causal_read (wsrep, &gtid);
+ wsrep_status_t ret= wsrep->causal_read (wsrep, &thd->wsrep_sync_wait_gtid);
if (unlikely(WSREP_OK != ret))
{
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 1616bab695e..242227fd2a0 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -192,6 +192,7 @@ extern void wsrep_kill_mysql(THD *thd);
/* new defines */
extern void wsrep_stop_replication(THD *thd);
extern bool wsrep_start_replication();
+extern bool wsrep_must_sync_wait (THD* thd, uint mask = WSREP_SYNC_WAIT_BEFORE_READ);
extern bool wsrep_sync_wait (THD* thd, uint mask = WSREP_SYNC_WAIT_BEFORE_READ);
extern int wsrep_check_opts (int argc, char* const* argv);
extern void wsrep_prepend_PATH (const char* path);