Commit 6a370e43 authored by Marko Mäkelä's avatar Marko Mäkelä

Refactor TrxUndoRsegsIterator for further simplification

TrxUndoRsegs::append(): Remove.

TrxUndoRsegsIterator::set_next(): Add a debug assertion that
demonstrates that the merging of rollback segments never occurs.
Since MDEV-12289 or earlier, MariaDB 10.2 will not make any
temporary undo log accessible to the purge subsystem.
(Also MySQL 5.7 would skip the purge of any undo log for
temporary tables, but not before parsing and buffering those
temporary undo log records.)
parent 6ae7fa68
...@@ -97,10 +97,10 @@ class TrxUndoRsegs { ...@@ -97,10 +97,10 @@ class TrxUndoRsegs {
trx_rsegs_t; trx_rsegs_t;
public: public:
typedef trx_rsegs_t::iterator iterator; typedef trx_rsegs_t::iterator iterator;
typedef trx_rsegs_t::const_iterator const_iterator;
/** Default constructor */ /** Default constructor */
TrxUndoRsegs(trx_id_t trx_no = 0) : m_trx_no(trx_no) {} TrxUndoRsegs() {}
/** Constructor */ /** Constructor */
TrxUndoRsegs(trx_rseg_t& rseg) TrxUndoRsegs(trx_rseg_t& rseg)
: m_trx_no(rseg.last_trx_no), m_rsegs(1, &rseg) {} : m_trx_no(rseg.last_trx_no), m_rsegs(1, &rseg) {}
...@@ -108,28 +108,15 @@ class TrxUndoRsegs { ...@@ -108,28 +108,15 @@ class TrxUndoRsegs {
TrxUndoRsegs(trx_id_t trx_no, trx_rseg_t& rseg) TrxUndoRsegs(trx_id_t trx_no, trx_rseg_t& rseg)
: m_trx_no(trx_no), m_rsegs(1, &rseg) {} : m_trx_no(trx_no), m_rsegs(1, &rseg) {}
/** Get transaction number /** Get the commit number */
@return trx_id_t - get transaction number. */ trx_id_t get_trx_no() const { return m_trx_no; }
trx_id_t get_trx_no() const
{
return(m_trx_no);
}
bool empty() const { return m_rsegs.empty(); } bool empty() const { return m_rsegs.empty(); }
void erase(iterator& it) { m_rsegs.erase(it); } void erase(iterator& it) { m_rsegs.erase(it); }
iterator begin() { return(m_rsegs.begin()); } iterator begin() { return(m_rsegs.begin()); }
iterator end() { return(m_rsegs.end()); } iterator end() { return(m_rsegs.end()); }
const_iterator begin() const { return m_rsegs.begin(); }
/** Append rollback segments from referred instance to current const_iterator end() const { return m_rsegs.end(); }
instance. */
void append(const TrxUndoRsegs& append_from)
{
ut_ad(get_trx_no() == append_from.get_trx_no());
m_rsegs.insert(m_rsegs.end(),
append_from.m_rsegs.begin(),
append_from.m_rsegs.end());
}
/** Compare two TrxUndoRsegs based on trx_no. /** Compare two TrxUndoRsegs based on trx_no.
@param elem1 first element to compare @param elem1 first element to compare
...@@ -141,7 +128,7 @@ class TrxUndoRsegs { ...@@ -141,7 +128,7 @@ class TrxUndoRsegs {
} }
private: private:
/** The rollback segments transaction number. */ /** Copy trx_rseg_t::last_trx_no */
trx_id_t m_trx_no; trx_id_t m_trx_no;
/** Rollback segments of a transaction, scheduled for purge. */ /** Rollback segments of a transaction, scheduled for purge. */
...@@ -153,14 +140,12 @@ typedef std::priority_queue< ...@@ -153,14 +140,12 @@ typedef std::priority_queue<
std::vector<TrxUndoRsegs, ut_allocator<TrxUndoRsegs> >, std::vector<TrxUndoRsegs, ut_allocator<TrxUndoRsegs> >,
TrxUndoRsegs> purge_pq_t; TrxUndoRsegs> purge_pq_t;
/** /** Chooses the rollback segment with the oldest committed transaction */
Chooses the rollback segment with the smallest trx_no. */
struct TrxUndoRsegsIterator { struct TrxUndoRsegsIterator {
/** Constructor */ /** Constructor */
TrxUndoRsegsIterator(); inline TrxUndoRsegsIterator();
/** Sets the next rseg to purge in purge_sys. /** Sets the next rseg to purge in purge_sys.
Executed in the purge coordinator thread.
@return whether anything is to be purged */ @return whether anything is to be purged */
inline bool set_next(); inline bool set_next();
...@@ -170,13 +155,9 @@ struct TrxUndoRsegsIterator { ...@@ -170,13 +155,9 @@ struct TrxUndoRsegsIterator {
TrxUndoRsegsIterator& operator=(const TrxUndoRsegsIterator&); TrxUndoRsegsIterator& operator=(const TrxUndoRsegsIterator&);
/** The current element to process */ /** The current element to process */
TrxUndoRsegs m_trx_undo_rsegs; TrxUndoRsegs m_rsegs;
/** Track the current element in m_rsegs */
/** Track the current element in m_trx_undo_rseg */ TrxUndoRsegs::const_iterator m_iter;
TrxUndoRsegs::iterator m_iter;
/** Sentinel value */
static const TrxUndoRsegs NullElement;
}; };
/* Namespace to hold all the related functions and variables need for truncate /* Namespace to hold all the related functions and variables need for truncate
......
...@@ -64,21 +64,18 @@ my_bool srv_purge_view_update_only_debug; ...@@ -64,21 +64,18 @@ my_bool srv_purge_view_update_only_debug;
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/** Sentinel value */ /** Sentinel value */
const TrxUndoRsegs TrxUndoRsegsIterator::NullElement(TRX_ID_MAX); static const TrxUndoRsegs NullElement;
/** Constructor */ /** Default constructor */
TrxUndoRsegsIterator::TrxUndoRsegsIterator() inline TrxUndoRsegsIterator::TrxUndoRsegsIterator()
: : m_rsegs(NullElement), m_iter(m_rsegs.begin())
m_trx_undo_rsegs(NullElement),
m_iter(m_trx_undo_rsegs.end())
{ {
} }
/** Sets the next rseg to purge in purge_sys. /** Sets the next rseg to purge in purge_sys.
Executed in the purge coordinator thread.
@return whether anything is to be purged */ @return whether anything is to be purged */
inline inline bool TrxUndoRsegsIterator::set_next()
bool
TrxUndoRsegsIterator::set_next()
{ {
mutex_enter(&purge_sys->pq_mutex); mutex_enter(&purge_sys->pq_mutex);
...@@ -87,65 +84,36 @@ TrxUndoRsegsIterator::set_next() ...@@ -87,65 +84,36 @@ TrxUndoRsegsIterator::set_next()
/* Check if there are more rsegs to process in the /* Check if there are more rsegs to process in the
current element. */ current element. */
if (m_iter != m_trx_undo_rsegs.end()) { if (m_iter != m_rsegs.end()) {
/* We are still processing rollback segment from /* We are still processing rollback segment from
the same transaction and so expected transaction the same transaction and so expected transaction
number shouldn't increase. Undo increment of number shouldn't increase. Undo the increment of
expected trx_no done by caller assuming rollback expected trx_no done by caller assuming rollback
segments from given transaction are done. */ segments from given transaction are done. */
purge_sys->tail.trx_no = (*m_iter)->last_trx_no; purge_sys->tail.trx_no = (*m_iter)->last_trx_no;
} else if (!purge_sys->purge_queue.empty()) { } else if (!purge_sys->purge_queue.empty()) {
m_rsegs = purge_sys->purge_queue.top();
/* Read the next element from the queue. purge_sys->purge_queue.pop();
Combine elements if they have same transaction number. ut_ad(purge_sys->purge_queue.empty()
This can happen if a transaction shares redo rollback segment || purge_sys->purge_queue.top().get_trx_no()
with another transaction that has already added it to purge != m_rsegs.get_trx_no());
queue and former transaction also needs to schedule non-redo m_iter = m_rsegs.begin();
rollback segment for purge. */
m_trx_undo_rsegs = NullElement;
purge_pq_t& purge_queue = purge_sys->purge_queue;
while (!purge_queue.empty()) {
if (m_trx_undo_rsegs.get_trx_no() == TRX_ID_MAX) {
m_trx_undo_rsegs = purge_queue.top();
} else if (purge_queue.top().get_trx_no() ==
m_trx_undo_rsegs.get_trx_no()) {
m_trx_undo_rsegs.append(
purge_queue.top());
} else {
break;
}
purge_queue.pop();
}
m_iter = m_trx_undo_rsegs.begin();
} else { } else {
/* Queue is empty, reset iterator. */ /* Queue is empty, reset iterator. */
m_trx_undo_rsegs = NullElement;
m_iter = m_trx_undo_rsegs.end();
mutex_exit(&purge_sys->pq_mutex);
purge_sys->rseg = NULL; purge_sys->rseg = NULL;
mutex_exit(&purge_sys->pq_mutex);
m_rsegs = NullElement;
m_iter = m_rsegs.begin();
return false; return false;
} }
purge_sys->rseg = *m_iter++; purge_sys->rseg = *m_iter++;
mutex_exit(&purge_sys->pq_mutex); mutex_exit(&purge_sys->pq_mutex);
ut_a(purge_sys->rseg != NULL);
mutex_enter(&purge_sys->rseg->mutex); mutex_enter(&purge_sys->rseg->mutex);
ut_a(purge_sys->rseg->last_page_no != FIL_NULL); ut_a(purge_sys->rseg->last_page_no != FIL_NULL);
ut_ad(purge_sys->rseg->last_trx_no == m_trx_undo_rsegs.get_trx_no()); ut_ad(purge_sys->rseg->last_trx_no == m_rsegs.get_trx_no());
/* We assume in purge of externally stored fields that space id is /* We assume in purge of externally stored fields that space id is
in the range of UNDO tablespace space ids */ in the range of UNDO tablespace space ids */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment