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

mysql 表充一个库到其他库_mysql 表充一个库到其他库

1.1继承自Sql_alloc 在sql_alloc.h文件中

MySQL standard memory allocator class. You have to inherit the class in order to use it.

mysql 表充一个库到其他库_mysql_02

1.2关键成员

TABLE *table 正在打开的表格

handlerton handler真正调用的存储引擎

MRR 多范围读取 https://cloud.tencent.com/developer/article/2343999

mysql 表充一个库到其他库_mysql 表充一个库到其他库_03


•MultiRangeRead MRR

mysql 表充一个库到其他库_android_04

1.3关键成员

MySQL的batch模式,其实也就是批处理模式

mysql 表充一个库到其他库_mysql_05

1.4ha_* 方法蔟

私有虚拟API的包裹方法 具体的方法实现在handler.cc中

mysql 表充一个库到其他库_mysql 表充一个库到其他库_06

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情况下存在重复条目的表和键的名称。

mysql 表充一个库到其他库_存储引擎_07

2.ha_* 方法蔟的具体实现 handler.cc中

2.1ha_open 打开数据库的handler

mysql 表充一个库到其他库_mysql_08


关键函数open(name,O_RDONLY,test_if_locked) 根据存储引擎打开 table Creates and opens a handle to a table which already exists in an InnoDB database.

mysql 表充一个库到其他库_mysql 表充一个库到其他库_09


有PSI 表接口时,调用open_table函数 Performance schema instrumentation interface

mysql 表充一个库到其他库_存储引擎_10


•MySQL PSI 简介 psi.h中 MySQL Performance Schema (PSI)是MySQL数据库的一个特性,它提供了一种轻量级的、低开销的方法来收集MySQL服务器的性能数据。它可以帮助用户更好地了解MySQL服务器的性能瓶颈,从而更好地优化MySQL服务器的性能。PSI提供了一组表,这些表包含了MySQL服务器的各种性能数据,例如锁等待、查询执行时间、I/O操作等。用户可以使用这些表来分析MySQL服务器的性能瓶颈,并采取相应的措施来优化MySQL服务器的性能

mysql 表充一个库到其他库_存储引擎_11


::: hljs-center

打开base table

:::

2.2 ha_close 关闭handler

mysql 表充一个库到其他库_android_12


调用存储引擎层的close() 方法

2.3 ha_index_init 索引使用的初始化

mysql 表充一个库到其他库_mysql_13

调用存储层函数: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.

mysql 表充一个库到其他库_mysql_14

2.4 ha_index_end 终止使用索引

mysql 表充一个库到其他库_mysql_15


调用存储层函数 ha_innobase::index_end(void)

mysql 表充一个库到其他库_mysql_16

2.5 ha_rnd_init(bool scan) Initialize table for random read or scan.

mysql 表充一个库到其他库_存储引擎_17

handler.h的定义

mysql 表充一个库到其他库_mysql 表充一个库到其他库_18


调用存储层函数 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.

mysql 表充一个库到其他库_数据库_19

2.7 ha_rnd_next(uchar *buf) Read next row via random scan.

mysql 表充一个库到其他库_android_20


调用存储引擎层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).

mysql 表充一个库到其他库_mysql 表充一个库到其他库_21

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

mysql 表充一个库到其他库_数据库_22

2.8 ha_rnd_pos(uchar *buf, uchar *pos) Read row via random scan from position.

mysql 表充一个库到其他库_android_23


调用存储引擎层的int ha_innobase::rnd_pos()函数 Fetches a row from the table based on a row reference.

mysql 表充一个库到其他库_mysql 表充一个库到其他库_24

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,则从索引的第一个键开始。 这特别用于多读取范围。

mysql 表充一个库到其他库_mysql 表充一个库到其他库_25


调用了index_read_map()函数 计算key的长度,实际调用存储引擎层的index_read()函数

mysql 表充一个库到其他库_存储引擎_26


int ha_innobase::index_read()

mysql 表充一个库到其他库_mysql_27

注意:在某些存储引擎中是有直接实现index_read_map()函数的 比如heap、myisam(不包括innodb)

mysql 表充一个库到其他库_mysql_28

2.10 ha_index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map)

mysql 表充一个库到其他库_mysql_29

调用index_read_last_map()函数,本质调用存储引擎层的index_read_last()函数。与上面类似,heap、myisam中有实现,innodb中没有。

mysql 表充一个库到其他库_存储引擎_30


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.

mysql 表充一个库到其他库_mysql_31

2.11 ha_index_next_same(uchar *buf, const uchar *key, uint keylen) Reads the next same row via index.

mysql 表充一个库到其他库_mysql 表充一个库到其他库_32

调用index_next_same()函数,本质上对应到存储引擎中的函数。

mysql 表充一个库到其他库_mysql_33

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.

mysql 表充一个库到其他库_mysql 表充一个库到其他库_34

3handler.h中的其他成员

3.1 bool is_ignorable_error(int error) 判断错误是否可以被忽略 warnings的产生

mysql 表充一个库到其他库_mysql 表充一个库到其他库_35


具体实现 对error代码case 处理

mysql 表充一个库到其他库_数据库_36


类似的有:bool is_fatal_error(int error) 致命错误 其中 fatal error是指 SP处理程序无法处理的错误,并且不会在从属服务器上重试

3.2records() 和 ha_records()

Public function wrapping the actual handler call, and doing error checking.

mysql 表充一个库到其他库_mysql_37

3.3read_first_row

只用在读表格的第一行 innoDB引擎中的表不用这个,用rnd_next()

mysql 表充一个库到其他库_mysql_38

3.4 position:游标的位置,默认指向record的当前行 在innodb实现中 clustered index,不太合逻辑。

mysql 表充一个库到其他库_mysql_39

3.5锁相关的signal

避免不必要的等待 update、delete 锁住下一行时 return 1 如果不符合where条件,skip 之

mysql 表充一个库到其他库_mysql 表充一个库到其他库_40


lock_count、store_lock

mysql 表充一个库到其他库_数据库_41

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的方式来实现接口的访问,对表及事务的相关操作都是通过这种方式来访问相关的引擎插件的。

mysql 表充一个库到其他库_mysql_42

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

mysql 表充一个库到其他库_mysql_43

4.5 int (*get_tablespace) 获取表空间

mysql 表充一个库到其他库_数据库_44

4.6 handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root)

mysql 表充一个库到其他库_存储引擎_45


在innodb层,是调用了innobase_create_handler()这个函数 handler/ha_innodb.cc中 条件 innodb的type、定义了partition,调用ha_innoport()

mysql 表充一个库到其他库_数据库_46