Обнаружение таблиц (до версии 10.0.2)
Эта страница описывает старый API обнаружения, созданный в MySQL для кластера NDB. Он больше не работает в MariaDB. Новый API обнаружения таблиц описан здесь.
Он состоит из четырёх частей.
Во-первых, когда сервер обнаруживает, что таблица (например, упомянутая в запросе SELECT) не существует, он спрашивает каждый движок, знает ли он что-нибудь об этой таблице. Для этого используется метод discover() обработчика.
int discover(handlerton *hton, THD* thd, const char *db, const char *name,
unsigned char **frmblob, size_t *frmlen);
Он принимает базу данных и имя таблицы в качестве аргументов и возвращает 0, если таблица существует в движке, и 1 в противном случае. Если возвращено 0, предполагается выделение (с помощью my_malloc()) буфера и сохранение полного двоичного изображения файла .frm этой таблицы. Сервер запишет его на диск, создавая .frm таблицы. Параметры вывода frmblob и frmlen используются для возвращения информации о буфере вызывающей стороне. Вызывающая сторона отвечает за освобождение буфера с помощью my_free().
Во-вторых, в некоторых случаях серверу нужно только узнать, существует ли таблица, но ему не нужно её открывать и он не будет использовать её изображение файла .frm. Тогда использование метода discover() будет избыточным, и сервер использует лёгкий метод table_exists_in_engine(). Этот метод определяется как
int table_exists_in_engine(handlerton *hton, THD* thd,
const char *db, const char *name);
и возвращает один из HA_ERR_ кодов, обычно HA_ERR_NO_SUCH_TABLE или
HA_ERR_TABLE_EXIST.
В-третьих, может возникнуть ситуация, когда сервер считает, что таблица существует (он нашёл и успешно прочитал файл .frm), но с точки зрения движка файл .frm некорректен. Например, таблица уже была удалена из движка или её определение было изменено (снова, только в движке). В этом случае файл .frm устарел, и серверу нужно повторно обнаружить таблицу. Движок сообщает об этом серверу, возвращая код ошибки HA_ERR_TABLE_DEF_CHANGED из метода open() обработчика. Получив эту ошибку, сервер использует метод discover() для получения нового изображения .frm. Это также означает, что после открытия таблицы сервер не ожидает изменения её метаданных. Таким образом, движок должен гарантировать (возможно, с помощью какой-то блокировки), что метаданные таблицы не могут быть изменены, пока таблица остаётся открытой.
И, наконец, пользователь может захотеть получить список таблиц в определённой базе данных. С помощью SHOW TABLES или путём запроса к таблицам INFORMATION_SCHEMA. Пользователь ожидает увидеть все таблицы, но сервер не может обнаруживать их по одной, потому что не знает имён таблиц. В этом случае сервер использует специальный метод обнаружения. Это метод find_files() в обработчике, определённый как
int find_files(handlerton *hton, THD *thd,
const char *db, const char *path,
const char *wild, bool dir, List<LEX_STRING> *files);
и он, как правило, для API движка хранения данных, возвращает 0 при успехе и 1 при ошибке. Аргументы означают db - имя базы данных, path - путь к ней, wild - шаблон подстановки SQL (например, из SHOW TABLES LIKE '...', а dir, если задано, означает обнаружение баз данных вместо таблиц.
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/table-discovery-before-1002/