1.class handler :public Sql_alloc 在sql/handler.h中
总体介绍 The handler class is the interface for dynamically loadable storage engines. Functions in this class accept and return table columns data. TableRecordFormat 和 KeyTupleFormat
1.1继承自Sql_alloc 在sql_alloc.h文件中
MySQL standard memory allocator class. You have to inherit the class in order to use it.
1.2关键成员
TABLE *table 正在打开的表格
handlerton handler真正调用的存储引擎
MRR 多范围读取 https://cloud.tencent.com/developer/article/2343999
•MultiRangeRead MRR
1.3关键成员
MySQL的batch模式,其实也就是批处理模式
1.4ha_* 方法蔟
私有虚拟API的包裹方法 具体的方法实现在handler.cc中
get_foreign_dup_key(char *child_table_name,
uint child_table_name_len,
char *child_key_name,
uint child_key_name_len)
检索HA_ERR_FOREIGN_duplicate_key情况下存在重复条目的表和键的名称。
2.ha_* 方法蔟的具体实现 handler.cc中
2.1ha_open 打开数据库的handler
关键函数open(name,O_RDONLY,test_if_locked) 根据存储引擎打开 table Creates and opens a handle to a table which already exists in an InnoDB database.
有PSI 表接口时,调用open_table函数 Performance schema instrumentation interface
•MySQL PSI 简介 psi.h中 MySQL Performance Schema (PSI)是MySQL数据库的一个特性,它提供了一种轻量级的、低开销的方法来收集MySQL服务器的性能数据。它可以帮助用户更好地了解MySQL服务器的性能瓶颈,从而更好地优化MySQL服务器的性能。PSI提供了一组表,这些表包含了MySQL服务器的各种性能数据,例如锁等待、查询执行时间、I/O操作等。用户可以使用这些表来分析MySQL服务器的性能瓶颈,并采取相应的措施来优化MySQL服务器的性能
::: hljs-center
打开base table
:::
2.2 ha_close 关闭handler
调用存储引擎层的close() 方法
2.3 ha_index_init 索引使用的初始化
调用存储层函数:result= index_init(idx, sorted) 该方法首先在handler.h中定义的虚拟方法,调用时由上面的ha_使用,必须在存储引擎层进行覆盖。 Low-level primitives for storage engines. These should be overridden by the storage engine class. To call these methods, use the corresponding 'ha_’ method above.
2.4 ha_index_end 终止使用索引
调用存储层函数 ha_innobase::index_end(void)
2.5 ha_rnd_init(bool scan) Initialize table for random read or scan.
handler.h的定义
调用存储层函数 ha_innobase::rnd_init() Initialize a table scan.
2.6 ha_rnd_end() End use of random access.
调用存储引擎层ha_innobase::rnd_end(void) Ends a table scan.
2.7 ha_rnd_next(uchar *buf) Read next row via random scan.
调用存储引擎层ha_innobase::rnd_next(uchar* buf) Reads the next row in a table scan (also used to read the FIRST row in a table scan).
bool m_update_generated_read_fields; handler.h中 must ensure that virtual generated columns are calculated before they return. statue flag的目的:to avoid redundant calculations, for performance
2.8 ha_rnd_pos(uchar *buf, uchar *pos) Read row via random scan from position.
调用存储引擎层的int ha_innobase::rnd_pos()函数 Fetches a row from the table based on a row reference.
2.9 ha_index_read_map(uchar *buf, const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
Read [part of] row via [part of] index Positions an index cursor to the index specified in the handle. Fetches the row if available. If the key value is null, begin at the first key of the index. This is particularly used in conjunction 同时发生 with multi read ranges. 将索引游标定位到句柄中指定的索引。获取行(如果可用)。如果键值为null,则从索引的第一个键开始。 这特别用于多读取范围。
调用了index_read_map()函数 计算key的长度,实际调用存储引擎层的index_read()函数
int ha_innobase::index_read()
注意:在某些存储引擎中是有直接实现index_read_map()函数的 比如heap、myisam(不包括innodb)
2.10 ha_index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map)
调用index_read_last_map()函数,本质调用存储引擎层的index_read_last()函数。与上面类似,heap、myisam中有实现,innodb中没有。
ha_index_read_idx_map(uchar *buf, uint index,
const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function find_flag) Initializes an index and read it (与前序类似)
其他ha_index_next ha_index_prev ha_index_first ha_index_last,调用相应的index_*函数,本质上存储引擎都有对应的实现 下图以innodb的index_next为例。 Reads the next row from a cursor, which must have previously been positioned using index_read.
2.11 ha_index_next_same(uchar *buf, const uchar *key, uint keylen) Reads the next same row via index.
调用index_next_same()函数,本质上对应到存储引擎中的函数。
2.12 ha_reset() Check handler usage and reset state of file to after ‘open’ can be called regardless of it is locked or not.
3handler.h中的其他成员
3.1 bool is_ignorable_error(int error) 判断错误是否可以被忽略 warnings的产生
具体实现 对error代码case 处理
类似的有:bool is_fatal_error(int error) 致命错误 其中 fatal error是指 SP处理程序无法处理的错误,并且不会在从属服务器上重试
3.2records() 和 ha_records()
Public function wrapping the actual handler call, and doing error checking.
3.3read_first_row
只用在读表格的第一行 innoDB引擎中的表不用这个,用rnd_next()
3.4 position:游标的位置,默认指向record的当前行 在innodb实现中 clustered index,不太合逻辑。
3.5锁相关的signal
避免不必要的等待 update、delete 锁住下一行时 return 1 如果不符合where条件,skip 之
lock_count、store_lock
4 handlerton handler.h中
4.1整体描述
handlerton: handlerton is a singleton structure - one instance per storage engine - to provide access to storage engine functionality that works on the “global” level (unlike handler class that works on a per-table basis) usually handlerton instance is defined statically in ha_xxx.cc as static handlerton { … } xxx_hton; 数据库引擎通过这个handlerton的方式来实现接口的访问,对表及事务的相关操作都是通过这种方式来访问相关的引擎插件的。
4.2变量
state:if the engine is available or not.
db_type:determine the correct storage engine.
slot:each storage engine has it’s own memory area (actually a pointer) in the thd, for storing per-connection information. It is accessed as thd->ha_data[xxx_hton.slot]
savepoint_offset: to store per-savepoint data storage engine is provided with an area of a requested size (0 is ok here)
4.3方法
int (*close_connection)(handlerton *hton, THD *thd) only called if thd->ha_data[xxx_hton.slot] is non-zero void (*kill_connection)(handlerton *hton, THD *thd) Terminate connection/statement notification
4.4 uint (*partition_flags)()
是否supports partitioned tables
4.5 int (*get_tablespace) 获取表空间
4.6 handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root)
在innodb层,是调用了innobase_create_handler()这个函数 handler/ha_innodb.cc中 条件 innodb的type、定义了partition,调用ha_innoport()