263 lines
7.8 KiB
C++
263 lines
7.8 KiB
C++
/* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License, version 2.0,
|
|
as published by the Free Software Foundation.
|
|
|
|
This program is also distributed with certain software (including
|
|
but not limited to OpenSSL) that is licensed under separate terms,
|
|
as designated in a particular file or component or in included license
|
|
documentation. The authors of MySQL hereby grant you an additional
|
|
permission to link the program and your derivative works with the
|
|
separately licensed software that they have included with MySQL.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License, version 2.0, for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
|
|
#ifndef DD_CACHE__STORAGE_ADAPTER_INCLUDED
|
|
#define DD_CACHE__STORAGE_ADAPTER_INCLUDED
|
|
|
|
#include <stddef.h>
|
|
|
|
#include "mysql/components/services/mysql_mutex_bits.h"
|
|
#include "mysql/psi/mysql_mutex.h"
|
|
#include "mysql/psi/psi_base.h"
|
|
#include "sql/dd/cache/object_registry.h" // Object_registry
|
|
#include "sql/dd/object_id.h"
|
|
#include "sql/handler.h" // enum_tx_isolation
|
|
#include "thr_mutex.h"
|
|
|
|
class THD;
|
|
|
|
namespace dd_cache_unittest {
|
|
class CacheStorageTest;
|
|
}
|
|
|
|
namespace dd {
|
|
|
|
namespace cache {
|
|
|
|
/**
|
|
Handling of access to persistent storage.
|
|
|
|
This class provides static template functions that manipulates an object on
|
|
persistent storage based on the submitted key and object type. There is also
|
|
an object registry instance to keep the core DD objects that are needed to
|
|
handle cache misses for table meta data. The storage adapter owns the objects
|
|
in the core registry. When adding objects to the registry using core_store(),
|
|
the storage adapter will clone the object and take ownership of the clone.
|
|
When retrieving objects from the registry using core_get(), a clone of the
|
|
object will be returned, and this is therefore owned by the caller.
|
|
*/
|
|
|
|
class Storage_adapter {
|
|
friend class dd_cache_unittest::CacheStorageTest;
|
|
|
|
private:
|
|
/**
|
|
Use an id not starting at 1 to make it easy to recognize ids generated
|
|
before objects are stored persistently.
|
|
*/
|
|
|
|
static const Object_id FIRST_OID = 10001;
|
|
|
|
/**
|
|
Generate a new object id for a registry partition.
|
|
|
|
Simulate an auto increment column. Used when the server is starting,
|
|
while the scaffolding is being built.
|
|
|
|
@tparam T Object registry partition.
|
|
|
|
@return Next object id to be used.
|
|
*/
|
|
|
|
template <typename T>
|
|
Object_id next_oid();
|
|
|
|
/**
|
|
Get a dictionary object from core storage.
|
|
|
|
A clone of the registry object will be returned, owned by the caller.
|
|
|
|
@tparam K Key type.
|
|
@tparam T Dictionary object type.
|
|
@param key Key for which to get the object.
|
|
@param [out] object Object retrieved, possibly nullptr if not present.
|
|
*/
|
|
|
|
template <typename K, typename T>
|
|
void core_get(const K &key, const T **object);
|
|
|
|
Object_registry m_core_registry; // Object registry storing core DD objects.
|
|
mysql_mutex_t m_lock; // Single mutex to protect the registry.
|
|
static bool s_use_fake_storage; // Whether to use the core registry to
|
|
// simulate the storage engine.
|
|
|
|
Storage_adapter() {
|
|
mysql_mutex_init(PSI_NOT_INSTRUMENTED, &m_lock, MY_MUTEX_INIT_FAST);
|
|
}
|
|
|
|
~Storage_adapter() {
|
|
mysql_mutex_lock(&m_lock);
|
|
m_core_registry.erase_all();
|
|
mysql_mutex_unlock(&m_lock);
|
|
mysql_mutex_destroy(&m_lock);
|
|
}
|
|
|
|
public:
|
|
static Storage_adapter *instance();
|
|
|
|
/**
|
|
Get the number of core objects in a registry partition.
|
|
|
|
@tparam T Dictionary object type.
|
|
@return Number of elements.
|
|
*/
|
|
|
|
template <typename T>
|
|
size_t core_size();
|
|
|
|
/**
|
|
Get a dictionary object id from core storage.
|
|
|
|
@tparam T Dictionary object type.
|
|
@param key Name key for which to get the object id.
|
|
@return Object id, INVALID_OBJECT_ID if the object is not present.
|
|
*/
|
|
|
|
template <typename T>
|
|
Object_id core_get_id(const typename T::Name_key &key);
|
|
|
|
/**
|
|
Update the dd object in the core registry. This is a noop unless
|
|
this member function is overloaded for a given type. See below.
|
|
*/
|
|
template <typename T>
|
|
void core_update(const T *) {}
|
|
|
|
/**
|
|
Overload of core_update for dd::Tablespace. Currently the core
|
|
registry can only be updated for the DD tablespace when
|
|
encrypting it. A clone of the dd::Tablespace object passed in is
|
|
stored in the registry.
|
|
|
|
@param new_tsp the new dd::Tablespace object to keep in the core registry.
|
|
*/
|
|
void core_update(const dd::Tablespace *new_tsp);
|
|
|
|
/**
|
|
Get a dictionary object from persistent storage.
|
|
|
|
Create an access key based on the submitted key, and find the record
|
|
from the appropriate table. Restore the record into a new dictionary
|
|
object.
|
|
|
|
@tparam K Key type.
|
|
@tparam T Dictionary object type.
|
|
@param thd Thread context.
|
|
@param key Key for which to get the object.
|
|
@param isolation Isolation level.
|
|
@param bypass_core_registry If set to true, get the object from the
|
|
DD tables. Needed during DD bootstrap.
|
|
@param [out] object Object retrieved, possibly NULL if not present.
|
|
|
|
@retval false No error.
|
|
@retval true Error.
|
|
*/
|
|
|
|
template <typename K, typename T>
|
|
static bool get(THD *thd, const K &key, enum_tx_isolation isolation,
|
|
bool bypass_core_registry, const T **object);
|
|
|
|
/**
|
|
Drop a dictionary object from core storage.
|
|
|
|
@tparam T Dictionary object type.
|
|
@param thd Thread context.
|
|
@param object Object to be dropped.
|
|
*/
|
|
|
|
template <typename T>
|
|
void core_drop(THD *thd, const T *object);
|
|
|
|
/**
|
|
Drop a dictionary object from persistent storage.
|
|
|
|
@tparam T Dictionary object type.
|
|
@param thd Thread context.
|
|
@param object Object to be dropped.
|
|
|
|
@retval false No error.
|
|
@retval true Error.
|
|
*/
|
|
|
|
template <typename T>
|
|
static bool drop(THD *thd, const T *object);
|
|
|
|
/**
|
|
Store a dictionary object to core storage.
|
|
|
|
A clone of the submitted object will be added to the core
|
|
storage. The caller is still the owner of the submitted
|
|
objecct.
|
|
|
|
@tparam T Dictionary object type.
|
|
@param thd Thread context.
|
|
@param object Object to be stored.
|
|
*/
|
|
|
|
template <typename T>
|
|
void core_store(THD *thd, T *object);
|
|
|
|
/**
|
|
Store a dictionary object to persistent storage.
|
|
|
|
@tparam T Dictionary object type.
|
|
@param thd Thread context.
|
|
@param object Object to be stored.
|
|
|
|
@retval false No error.
|
|
@retval true Error.
|
|
*/
|
|
|
|
template <typename T>
|
|
static bool store(THD *thd, T *object);
|
|
|
|
/**
|
|
Sync a dictionary object from persistent to core storage.
|
|
|
|
@tparam K Key type.
|
|
@tparam T Dictionary object type.
|
|
@param thd Thread context.
|
|
@param key Key for object to get from persistent storage.
|
|
@param object Object to drop from the core registry.
|
|
*/
|
|
|
|
template <typename T>
|
|
bool core_sync(THD *thd, const typename T::Name_key &key, const T *object);
|
|
|
|
/**
|
|
Remove and delete all elements and objects from core storage.
|
|
*/
|
|
|
|
void erase_all();
|
|
|
|
/**
|
|
Dump the contents of the core storage.
|
|
*/
|
|
|
|
void dump();
|
|
};
|
|
|
|
} // namespace cache
|
|
} // namespace dd
|
|
|
|
#endif // DD_CACHE__STORAGE_ADAPTER_INCLUDED
|