Use cache as long as a trx only performes reads
As before, the cache will be used if there is no ongoing transaction (includes autocommit being on), or if there is an explicitly read- only transaction. In addition, the cache will be used and populated during any other transaction as long as only pure read statements are executed. After first non-read statement, the use of the cache is disabled.
This commit is contained in:
@ -26,9 +26,18 @@ Currently there is **no** cache invalidation, apart from _time-to-live_.
|
|||||||
Resultsets of prepared statements are **not** cached.
|
Resultsets of prepared statements are **not** cached.
|
||||||
|
|
||||||
### Transactions
|
### Transactions
|
||||||
The cache will be used and populated **only** if there is _no_ on-going
|
The cache will be used and populated in the following circumstances:
|
||||||
transaction or if an on-going transaction is _explicitly_ read-only (that is,
|
|
||||||
`START TRANSACTION READ ONLY`).
|
* There is _no_ on-going transaction, that is, _autocommit_ is used,
|
||||||
|
* there is an _explicitly_ read-only transaction (that is,`START TRANSACTION
|
||||||
|
READ ONLY`) active, or
|
||||||
|
* there is a transaction active and _no_ statement that modify the database
|
||||||
|
has been performed.
|
||||||
|
|
||||||
|
In practice, the last bullet point basically means that if a transaction has
|
||||||
|
been started with `BEGIN` or `START TRANSACTION READ WRITE`, then the cache
|
||||||
|
will be used and populated until the first `UPDATE`, `INSERT` or `DELETE`
|
||||||
|
statement is encountered.
|
||||||
|
|
||||||
### Variables
|
### Variables
|
||||||
The cache key is effectively the entire _SELECT_ statement. However, the
|
The cache key is effectively the entire _SELECT_ statement. However, the
|
||||||
|
@ -8,6 +8,14 @@ release 2.1.0.
|
|||||||
For any problems you encounter, please consider submitting a bug
|
For any problems you encounter, please consider submitting a bug
|
||||||
report at [Jira](https://jira.mariadb.org).
|
report at [Jira](https://jira.mariadb.org).
|
||||||
|
|
||||||
|
## Changed Features
|
||||||
|
|
||||||
|
### Cache
|
||||||
|
|
||||||
|
The cache will now _also_ be used and populated in a transaction that is
|
||||||
|
_not_ explicitly read only, but only until the first statement that modifies
|
||||||
|
the database is encountered.
|
||||||
|
|
||||||
## Dropped Features
|
## Dropped Features
|
||||||
|
|
||||||
### MaxAdmin
|
### MaxAdmin
|
||||||
|
@ -41,6 +41,7 @@ CacheFilterSession::CacheFilterSession(MXS_SESSION* pSession, Cache* pCache, cha
|
|||||||
, m_zDefaultDb(zDefaultDb)
|
, m_zDefaultDb(zDefaultDb)
|
||||||
, m_zUseDb(NULL)
|
, m_zUseDb(NULL)
|
||||||
, m_refreshing(false)
|
, m_refreshing(false)
|
||||||
|
, m_is_read_only(true)
|
||||||
{
|
{
|
||||||
memset(m_key.data, 0, CACHE_KEY_MAXLEN);
|
memset(m_key.data, 0, CACHE_KEY_MAXLEN);
|
||||||
|
|
||||||
@ -130,7 +131,59 @@ int CacheFilterSession::routeQuery(GWBUF* pPacket)
|
|||||||
|
|
||||||
case MYSQL_COM_QUERY:
|
case MYSQL_COM_QUERY:
|
||||||
{
|
{
|
||||||
if (!session_trx_is_active(m_pSession) || session_trx_is_read_only(m_pSession))
|
bool consult_cache = false;
|
||||||
|
|
||||||
|
uint32_t type_mask = qc_get_type_mask(pPacket);
|
||||||
|
|
||||||
|
if (type_mask & QUERY_TYPE_BEGIN_TRX)
|
||||||
|
{
|
||||||
|
// When a transaction is started, we initially assume it is read-only.
|
||||||
|
m_is_read_only = true;
|
||||||
|
}
|
||||||
|
else if (!(type_mask & QUERY_TYPE_READ))
|
||||||
|
{
|
||||||
|
// Thereafter, if there's any non-read statement we mark it as non-readonly.
|
||||||
|
// Note that the state of m_is_read_only is not consulted if there is no
|
||||||
|
// on-going transaction of if there is an explicitly read-only transaction.
|
||||||
|
m_is_read_only = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!session_trx_is_active(m_pSession))
|
||||||
|
{
|
||||||
|
if (log_decisions())
|
||||||
|
{
|
||||||
|
MXS_NOTICE("Cache can be used and stored to, since there is no transaction.");
|
||||||
|
}
|
||||||
|
consult_cache = true;
|
||||||
|
}
|
||||||
|
else if (session_trx_is_read_only(m_pSession))
|
||||||
|
{
|
||||||
|
if (log_decisions())
|
||||||
|
{
|
||||||
|
MXS_NOTICE("Cache can be used and stored to since there is an explicitly "
|
||||||
|
"read-only transaction.");
|
||||||
|
}
|
||||||
|
consult_cache = true;
|
||||||
|
}
|
||||||
|
else if (m_is_read_only)
|
||||||
|
{
|
||||||
|
if (log_decisions())
|
||||||
|
{
|
||||||
|
MXS_NOTICE("Cache can be used and stored to, since the current transaction "
|
||||||
|
"(not explicitly read-only) has so far been read-only.");
|
||||||
|
}
|
||||||
|
consult_cache = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (log_decisions())
|
||||||
|
{
|
||||||
|
MXS_NOTICE("Cache can not be used, since a not explicitly read-only transaction "
|
||||||
|
"is active and the transaction has executed non-read statements.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (consult_cache)
|
||||||
{
|
{
|
||||||
// We do not care whether the query was fully parsed or not.
|
// We do not care whether the query was fully parsed or not.
|
||||||
// If a query cannot be fully parsed, the worst thing that can
|
// If a query cannot be fully parsed, the worst thing that can
|
||||||
@ -215,16 +268,6 @@ int CacheFilterSession::routeQuery(GWBUF* pPacket)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (log_decisions())
|
|
||||||
{
|
|
||||||
MXS_NOTICE("autocommit = %s and transaction state %s => Not using or "
|
|
||||||
"storing to cache.",
|
|
||||||
session_is_autocommit(m_pSession) ? "ON" : "OFF",
|
|
||||||
session_trx_state_to_string(session_get_trx_state(m_pSession)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -119,5 +119,6 @@ private:
|
|||||||
char* m_zDefaultDb; /**< The default database. */
|
char* m_zDefaultDb; /**< The default database. */
|
||||||
char* m_zUseDb; /**< Pending default database. Needs server response. */
|
char* m_zUseDb; /**< Pending default database. Needs server response. */
|
||||||
bool m_refreshing; /**< Whether the session is updating a stale cache entry. */
|
bool m_refreshing; /**< Whether the session is updating a stale cache entry. */
|
||||||
|
bool m_is_read_only;/**< Whether the current trx has been read-only in pratice. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user