Reduce usage of LOCK_open

Description

Requiremen: when this task is completed, get_table_share() shall not acquire LOCK_open.

Note: this task is not aiming to get rid of LOCK_open completely, further optimizations will be subject of other task(s).

New mutex shall be added to protect table specific variables. Suggested name: TABLE_SHARE::LOCK_table_share. We agreed not to use TABLE_SHARE::LOCK_ha_data because it is supposed to be used by storage engines and they may lock it for a long time.

get_table_share() uses the following variables protected by LOCK_open:
table_def_cache
table_def_shutdown_in_progress
last_table_id
TABLE_SHARE::ref_count
TABLE_SHARE::next
TABLE_SHARE:rev
TABLE_SHARE::m_flush_tickets
end_of_unused_share
oldest_unused_share
refresh_version

1. table_def_cache: Monty suggests to test rw-locks first and migrate to lf-hash later, Serg suggests lf-hash.

Svoj: for initial implementation we will use rw-locks, there are three open questions with lf_hash that may delay implementation: 1) safe iteration (snapshot), 2) unsafe iteration, 3) how to safely retrieve elements count. It should be easy to switch to lf_hash when they're solved.

2. table_def_shutdown_in_progress: not used directly by get_table_share(), but needs to be taken into account to be able to fix other functions easier. Updated only during shutdown when all client connections are closed. No lock should be needed, even need of this variable is questionable: why not to update refresh_version instead?

Svoj: this variable doesn't need locking indeed as it is used only during shutdown. We can't replace it's function by updating refresh_version, but we can replace it by setting table_def_size to 0.

3. last_table_id: simple id generator, use atomics.

4. TABLE_SHARE::ref_count: shall be protected by TABLE_SHARE::LOCK_table_share.

5. TABLE_SHARE::next, :rev, oldest_unused_share, end_of_unused_share: these variables are intended to effeciently free oldest share first. Shall be protected by global mutex: LOCK_unused_shares.

6. TABLE_SHARE::m_flush_tickets shall be protected by TABLE_SHARE::LOCK_table_share. It is needed to avoid LOCK_open when removing share from cache (e.g. purging unused shares in get_table_share() and release_table_share()).

7. refresh_version: use atomics.

Per request from Igor, Svoj analyzed if table_cache.cc provides black-box clean API to table definition cache. Unfortunately it does not give significant benefit over existing API and may complicate implementation of this task.

Environment

None

Status

Assignee

Sergey Vojtovich

Reporter

Sergey Vojtovich

Labels

None

External issue ID

None

External issue ID

None

Time tracking

72h

Fix versions

Priority

Major
Configure