diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2022-08-17 18:46:04 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2022-10-12 20:49:45 +0300 |
commit | 3cd2c1e8b6fa8435e634360c2ff63f5d645b65dc (patch) | |
tree | 9cb684504929ed314b124e1d1c4ddb0f90bbe818 /sql/sql_class.h | |
parent | 4fec99a2ba6034592d273d918402540d3d4fe772 (diff) | |
download | mariadb-git-3cd2c1e8b6fa8435e634360c2ff63f5d645b65dc.tar.gz |
MDEV-29299 SELECT from table with vcol index reports warning
As of now innodb does not store trx_id for each record in secondary index.
The idea behind is following: let us store only per-page max_trx_id, and
delete-mark the records when they are deleted/updated.
If the read starts, it rememders the lowest id of currently active
transaction. Innodb refers to it as trx->read_view->m_up_limit_id.
See also ReadView::open.
When the page is fetched, its max_trx_id is compared to m_up_limit_id.
If the value is lower, and the secondary index record is not delete-marked,
then this page is just safe to read as is. Else, a clustered index could be
needed ato access. See page_get_max_trx_id call in row_search_mvcc, and the
corresponding switch (row_search_idx_cond_check(...)) below.
Virtual columns are required to be updated in case if the record was
delete-marked. The motivation behind it is documented in
Row_sel_get_clust_rec_for_mysql::operator() near
row_sel_sec_rec_is_for_clust_rec call.
This was basically a description why virtual column computation can
normally happen during SELECT, and, generally, a vcol index access.
Sometimes stats tables are updated by innodb. This starts a new
transaction, and it can happen that it didn't finish to the moment of
SELECT execution, forcing virtual columns recomputation. If the result was
a something that normally outputs a warning, like division by zero, then
it could be outputted in a racy manner.
The solution is to suppress the warnings when a column is computed
for the described purpose.
ignore_wrnings argument is added innobase_get_computed_value.
Currently, it is only true for a call from
row_sel_sec_rec_is_for_clust_rec.
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r-- | sql/sql_class.h | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h index 7e06f0b0903..4d1f5b40db5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1856,6 +1856,21 @@ private: }; +struct Suppress_warnings_error_handler : public Internal_error_handler +{ + bool handle_condition(THD *thd, + uint sql_errno, + const char *sqlstate, + Sql_condition::enum_warning_level *level, + const char *msg, + Sql_condition **cond_hdl) + { + return *level == Sql_condition::WARN_LEVEL_WARN; + } +}; + + + /** Tables that were locked with LOCK TABLES statement. |