Bug #96147 Question about using ISO_READ_UNCOMMITTED isolation when retrieve dd object
Submitted: 10 Jul 2019 6:37 Modified: 17 Dec 2020 3:02
Reporter: Kang Wang Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: Data Dictionary Severity:S7 (Test Cases)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any

[10 Jul 2019 6:37] Kang Wang
Description:
I notice that when we need retrieve a object from data dictionary, for example, 
 the dd_open_table process, acquire_uncached_uncommitted will be invoked, which in turn may try to load it from persistence with ISO_READ_UNCOMMITTED isolation.

To understand the reason of using ISO_READ_UNCOMMITTED, I change it to ISO_READ_COMMITTED isolation in acquire_uncached_uncommitted as below:

  const typename T::Cache_partition *stored_object = nullptr;
  bool error = Shared_dictionary_cache::instance()->get_uncached(
      m_thd, key, ISO_READ_COMMITTED, &stored_object);
 
And expect some mtr case failed, but to my surprise, no case seems be impacted by this.

So my question is 
1. Why we use ISO_READ_UNCOMMITTED here;
2. If it is necessary, maybe some test case should be added to cover it.

Thanks

How to repeat:
Change ISO_READ_UNCOMMITTED isolation in acquire_uncached_uncommitted to ISO_READ_COMMITTED, but no testcase impacted.
[17 Jul 2019 13:42] MySQL Verification Team
Hi Mr. Wang,

Thank you for your bug report.

READ_UNCOMMITTED is used in order to make sure no other thread is changing the object, while it has been retrieved. This is faster than using locks. However, I concur that we have a test case missing here, which is the only reason why I am verifying this bug.

Verified as reported.
[18 Jul 2019 2:54] Kang Wang
Hi, thanks for your response.

Would you please explain in more detail what's the scenario we need READ_UNCOMMITTED or locks to read the most newest version.
[18 Jul 2019 13:05] MySQL Verification Team
This question will be addressed in our documentation, once this bug is fixed with a new test case.
[15 Dec 2020 15:17] MySQL Verification Team
Hi Mr. Wang,

Actually, our Development has analysed the entire code that you are referring to and came to the conclusion that this is not a bug.

Here is a full explanation and justification:

Quoting from the source code documentation: 

  /** 
    Retrieve an object by its object id without caching it. 

    The object is not cached but owned by the dictionary client, who 
    makes sure it is deleted. The object must not be released, and may not 
    be used as a parameter to the other dictionary client methods since it is 
    not known by the object registry. 

    @tparam       T       Dictionary object type. 
    @param        id      Object id to retrieve. 
    @param [out]  object  Dictionary object, if present; otherwise NULL. 

    @retval       false   No error. 
    @retval       true    Error (from reading the dictionary tables). 
   */ 

  template <typename T> 
  bool acquire_uncached(Object_id id, T **object) 
      MY_ATTRIBUTE((warn_unused_result)); 

In contrast the _UNCOMMITTED has the following comment: 

  /** 
    Retrieve a possibly uncommitted object by its object id without caching 
it. 

    The object is not cached but owned by the dictionary client, who 
    makes sure it is deleted. The object must not be released, and may not 
    be used as a parameter to the other dictionary client methods since it is 
    not known by the object registry. 

    When the object is read from the persistent tables, the transaction 
    isolation level is READ UNCOMMITTED. This is necessary to be able to 
    read uncommitted data from an earlier stage of the same session. 

    @tparam       T       Dictionary object type. 
    @param        id      Object id to retrieve. 
    @param [out]  object  Dictionary object, if present; otherwise nullptr. 

    @retval       false   No error. 
    @retval       true    Error (from reading the dictionary tables). 
   */ 

  template <typename T> 
  bool acquire_uncached_uncommitted(Object_id id, T **object) 
      MY_ATTRIBUTE((warn_unused_result)); 

So in short, there is no reason to change the isolation level for this 
function, since that semantic is provided by the former. That said, it is 
entirely possible that some places use the _uncommitted version when they 
could instead have relied on acquire_uncached(). ** DTJELDVO  dyre.tjeldvoll Sat Dec 12 2020 23:15:18 GMT+0200 (EET)*** 

Not a bug.
[17 Dec 2020 3:02] Kang Wang
Thanks for the response, I understand the different between the two function. But my question is for what scenario we must use ISO_READ_UNCOMMITTED rather than ISO_READ_COMMITTED. Or looking forward a new mtr case which will fail if I use ISO_READ_COMMITTED in acquire_uncached_uncommitted.