第三章 核心类、结构、变量和API
# 第三章 核心类、结构、变量和API
MySQL的源代码包含几十万行,并且还在不断增加。在其中找到方向颇具挑战。然而,如果你熟悉代码的核心元素及其各自的作用,这项任务就不会像最初看起来那么困难和令人生畏。本章的目的是为你打下基础,让你能够较为轻松地阅读大部分代码内容。
本章旨在进行一次代码知识的速成讲解。我们将重点关注那些对理解代码整体运行机制至关重要的核心元素。各个模块更具体的细节将在后面专门的章节中讨论。
在讨论各种代码元素时,由于篇幅限制,不可避免地会省略一些不太重要的类成员、API调用和全局变量。此外,在本书付梓之时,可能会出现一些新的代码元素,部分代码元素的名称或功能也可能会有一定程度的变化。不过,可以合理预期这种情况极少发生。我们在本章中讨论的大部分代码已经稳定,不会有重大改变。
我还必须指出,同样由于篇幅限制,我们不得不省略大量重要的类、结构和宏。但我希望,一旦你熟悉了我们所涵盖的内容,你将具备足够的基础,能够通过自己对代码的研究获取更多信息。
# THD
THD类定义了线程描述符。它包含与处理给定请求的线程相关的信息。每个客户端连接都由一个线程处理,每个线程都有一个描述符对象。创建线程并非仅仅是为了处理客户端请求,MySQL还有一些系统线程,比如复制从库线程和延迟插入线程。此外,还有一种特殊情况,即在线程不存在时创建线程描述符对象,比如在安装过程中服务器以引导模式运行来创建必要的系统表时。
由于客户端连接和线程之间关系紧密,MySQL开发者经常将 “线程” 和 “连接” 这两个术语互换使用。在讨论这个类时,我也会这么做。
THD可能是服务器代码中引用最频繁的类型。在大多数高层级调用中,它作为第一个参数传递。除了底层的存储和检索操作外,服务器内几乎所有重要操作都或多或少与这个类有关。熟悉它的成员能让你对服务器的整体架构和功能有更深入的了解。
THD在sql/sql_class.h
中定义,在sql/sql_class.cc
中实现。
通常,THD的实例由一个类型为THD*
的变量thd
指向。因此,如果你想在代码中查找使用这个类特定成员的地方,使用以下命令几乎总能找到:
grep "thd->var_name " sql/*.cc
这个类主要由数据成员组成,这也是我们讨论的主要内容。它有一些相当简单且不常使用的方法,由于篇幅限制,我们不会讨论这些方法。不过,一旦你理解了我们要讨论的数据成员的作用,从这些方法的源代码中你就能明白它们的功能。
表3-1列出了THD类中最主要的成员。需要注意的是,在4.1版本中,THD的部分内容被移到了新创建的Statement类中,并且THD成为了Statement的子类。该表还列出了Statement类中原本属于THD,且仍然经常被当作THD成员引用的公共成员。
成员定义 | 描述 |
---|---|
LEX* lex | 当前查询的解析树描述符。在4.1及更高版本中,它是Statement类的成员。 |
char* query | 当前查询的明文内容。在4.1及更高版本中,是Statement类的成员。 |
uint32 query_length | 当前查询的长度(以字节为单位)。在4.1及更高版本中,是Statement类的成员。 |
Item* free_list | 当前查询所有解析树节点的链表。用于执行后的清理工作(在sql/sql_parse.cc 中的free_items() 函数)。在4.1及更高版本中,是Statement类的成员。 |
MEM_ROOT mem_root | 线程内存池。供alloc_root() 和free_root() 函数使用。在4.1及更高版本中,是Statement类的成员。 |
NET net | 客户端连接描述符。 |
MEM_ROOT warn_root | 用于发出警告和错误信息的内存池。4.1版本新增。 |
Protocol* protocol | 客户端/服务器通信协议描述符。根据当前查询是否为预处理语句,它会指向不同的对象类型。4.1版本新增。 |
HASH user_vars | 用于存储查询中使用的用户变量的哈希表,例如:SET @a:=31; SELECT col1 FROM t1 WHERE col2=@a; |
String packet | 动态缓冲区,用于网络I/O。 |
struct system_variables variables | 此连接本地的系统变量,客户端可以更改这些变量。例如,SET LOCAL sort_buffer_size=256000 会将variables.sortbuff_size 的值设置为256000,并影响需要排序的ORDER BY 和GROUP BY 查询的处理。4.0版本新增。 |
Statement_map stmt_map | 此连接上所有预处理语句和游标的哈希表。4.1版本新增。 |
char* host | 客户端连接的主机。 |
char* priv_host | 客户端主机值,通过将连接套接字参数中的主机标识与mysql.user 表的内容进行匹配获得。换句话说,它是mysql.user 表中第一个匹配的主机列值。通常与host 相同。需要注意的是,在MySQL中,用户实体由两部分组成:用户名和主机名。例如,john@localhost 与john@www 是不同的用户。 |
char* user | 客户端传递给访问控制系统的用户。 |
char* priv_user | mysql.user 表中与传递给访问控制系统的用户值相匹配的值。通常与user 相同。 |
char* db | 当前选中的数据库。 |
uint32 db_length | db 指向的字符串长度。 |
char* ip | 客户端连接的IP地址,以字母数字形式表示。 |
char* host_or_ip | 如果可用,指向客户端连接的主机;否则(例如反向DNS查找失败时),指向包含客户端IP地址的字母数字字符串。 |
const char* proc_info | 指向SHOW PROCESSLIST 输出中Info 列的值。通常会在可能耗时较长的操作之前设置。对于排查性能问题非常有用。 |
ulong client_capabilities | 客户端能力的位掩码。就客户端 - 服务器协议而言,除了一些小的限制,所有MySQL版本都具有向前和向后兼容性。任何客户端都可以与任何服务器进行通信,无论版本如何。这个变量帮助服务器了解如何避免使旧版本的客户端产生混淆。它还用于跟踪客户端是否准备好使用SSL或压缩功能。 |
ulong master_access | 在MySQL访问控制系统中,权限可以在全局级别、数据库级别、表级别或列级别授予用户。这个变量是当前连接全局权限的位掩码。 |
ulong db_access | 当前连接上,客户端对当前选中数据库的权限位掩码。 |
ulong col_access | 这个变量的名称有点误导性。人们可能会认为,和其他两个类似,它是某种列访问的位掩码。然而,它只是一个临时变量,用于在处理SHOW TABLES 时确定用户对某个表是否具有某些权限。如果用户没有任何权限,该表将从输出中排除。 |
TABLE* open_tables | 此线程正在使用的常规表的链表。常规表是指通过诸如SELECT 、UPDATE 、DELETE 、INSERT 、REPLACE 或ALTER 等高层级查询引用的非临时表。HANDLER 查询中使用的表以及子查询中的派生表不属于这一类(参见handler_tables 和derived_tables )。这里列出的表会在查询结束时自动关闭。 |
TABLE* handler_tables | 此线程通过HANDLER OPEN 打开的表的链表。HANDLER 命令提供了一个绕过优化器直接访问底层存储引擎的接口。4.0版本新增。 |
TABLE* temporary_tables | 此线程创建的临时表的链表。临时表存在于给定连接的作用域内,可以通过CREATE TEMPORARY TABLE 手动创建,或者在优化器无法仅通过检查查询表来获取SELECT 结果时自动创建。 |
TABLE* derived_tables | 此查询中创建的派生表的链表。派生表是指在SELECT 语句的FROM 子句中由子查询生成的表。例如,在SELECT AVG(a) FROM (SELECT COUNT(*) AS a, b FROM t1 GROUP BY b) AS t_derived WHERE n > 100 中,t_derived 就是一个派生表。需要注意的是,“派生表” 这个术语在SQL标准中并没有精确的定义,因此MySQL文档更准确地将其称为 “FROM 子句中的子查询”。然而,由于历史原因,代码中一直使用 “派生” 这个术语。4.1版本新增。 |
MYSQL_LOCK* lock | 一个描述符结构,包含此线程在未使用LOCK TABLES 命令的情况下自动锁定的所有表的列表。当服务器处理诸如SELECT 、INSERT 或UPDATE 等常规查询并发现需要锁定时,就会发生这种类型的锁定。在任何给定时间,只能锁定一组表。必须一次性获取和释放整个表组的锁。如果这个变量设置为非零值,locked_tables (见下文)必须设置为0。 |
MYSQL_LOCK* locked_tables | 一个描述符结构,包含使用LOCK TABLES 锁定的所有表的列表。如果这个变量设置为非零值,lock 必须设置为0。 |
struct st_my_thread_var *mysys_var | 一个用于存储当前POSIX线程条件信息的结构,此线程可能正在等待该条件。在关闭服务器或使用KILL 命令终止线程时,用于唤醒睡眠的线程。条件会被人工广播,线程被唤醒后,检查它们的终止标志,然后意识到自己应该退出。详细信息可查看sql/sql_class.h 中的THD::enter_cond() 和THD::exit_cond() ,以及sql/sql_class.cc 中的THD::awake() 。如果线程没有等待任何条件,mysys_var 会设置为0。每当你计划使用pthread_cond_wait() 进行等待时,首先要调用THD::enter_cond() ,等待结束后,调用THD::exit_cond() 。 |
enum enum_server_command command | 当前服务器命令的类型。最常见的是COM_QUERY 。所有可能的类型都列在include/mysql_com.h 中enum_server_command 类型的定义下。 |
uint32 server_id | 这个变量在复制过程中用于从库的SQL线程。每个参与复制的服务器都必须在其配置文件中分配一个唯一的ID。当主库执行更新时,它会将源服务器ID记录到二进制更新日志中。当普通客户端执行更新时,源ID与服务器ID相同。然而,从库线程必须保留主库的源ID,以避免无限更新循环。通过在查询初始化时设置这个变量的值,调用者能够控制更新时记录哪个服务器ID。 |
delayed_insert *di | 当前延迟插入描述符。用于处理INSERT DELAYED 查询,该查询允许客户端请求在表可用时的某个未来时间插入行。 |
struct st_transactions transaction | 事务描述符。用于管理逻辑更新日志记录,跟踪已更改的表(用于查询缓存)。 |
Statement *current_statement | 当前预处理语句描述符。如果没有预处理语句,则设置为0。4.1版本新增。 |
uint server_status | 用于向客户端报告状态消息的位掩码。可能出现状态消息的情况包括:服务器处于事务中、存在一些额外的查询结果数据需要获取,或者查询没有有效地使用键。 |
ulonglong next_insert_id | MySQL支持生成自动递增的唯一键。每个表只允许有一个这样的键。不过,客户端可以通过执行SET INSERT_ID=value 来设置下一个生成键的值。执行此命令时,next_insert_id 会被设置为指定的值。 |
ulonglong last_insert_id | 设置为最后生成的自动递增唯一键的值。客户端可以通过SQL函数LAST_INSERT_ID() 获取这个值。客户端也可以通过执行SET LAST_INSERT_ID=value 手动设置它。 |
table_map used_tables | 一个位掩码,用于跟踪为了回答查询实际需要检查哪些表。优化器会大量使用这个变量。 |
USER_CONN *user_connect | 用户资源限制描述符。MySQL能够限制特定用户每小时允许的连接数和查询数。4.0版本新增。 |
CHARSET_INFO *db_charset | 当前数据库的字符集描述符。4.1版本新增。 |
List <MYSQL_ERROR> warn_list | 一些查询可能会产生警告信息。这些信息会存储在这个变量中,之后可以使用SHOW WARNINGS 查看。4.1版本新增。 |
ulong query_id | 当前执行查询的内部ID。每个新查询的ID都比前一个查询的值大1。 |
ulong thread_id | 服务器为这个线程分配的数字ID。这个值会显示在SHOW PROCESSLIST 输出的Id 列中,并作为KILL 命令的参数使用。 |
pthread_t real_id | 这个线程的POSIX线程ID。 |
uint system_thread | 对于非客户端线程,设置为非零值以指示线程类型。这类线程的示例包括延迟插入线程、复制从库线程、事件调度器和工作线程,以及NDB集群二进制日志线程。客户端线程设置为0。 |
bool slave_thread | 对于从库线程,设置为1(真)。 |
bool bootstrap | 对于引导线程,设置为1(真)。引导线程实际上并不是一个真正的线程。当使用–bootstrap 选项启动mysqld 时,它只是执行从标准输入读取的查询,一旦标准输入关闭就会退出。然而,会创建一个THD实例,并通过设置这个变量将其标记为特殊情况。引导执行模式在安装过程中用于创建服务器运行所需的系统表。 |
bool volatile killed | 当线程被要求终止时,设置为1(真)。每个线程在执行耗时操作时都必须频繁检查这个变量。如果该变量被设置,线程必须尽快执行清理工作并退出。 |
# NET结构体
NET结构体定义了一个网络连接描述符。MySQL在操作系统提供的用于客户端/服务器通信的协议之上,使用了一种相当复杂的协议。这个结构体是该协议实现的核心。
该协议定义了自己的数据包格式。一个数据包可以发送命令、消息或数据块。数据包可以被压缩,或者通过SSL层传输。
所有网络通信函数都以某种方式使用NET结构体,通常是将其作为参数接受。熟悉NET的成员是理解客户端/服务器通信协议的重要一步。
NET是一个相当小的结构体,我们可以完整地介绍它。它在include/mysql_com.h
中定义。用C语言编写的客户端库也使用相同的定义。这意味着NET结构体不可能有任何方法。不过,有许多函数接受NET*
作为参数,第5章将介绍这些函数。
表3-2列出了NET的成员。 表3-2 NET类的成员
成员定义 | 描述 |
---|---|
Vio* vio | 底层网络I/O套接字描述符。V代表虚拟(Virtual)。VIO抽象最初是为了支持SSL而创建的。现在它也用于支持Windows共享内存和命名管道连接。它还在许多其他方面促进了跨平台移植。 |
unsigned char *buff | 数据缓冲区的起始位置。 |
unsigned char *buff_end | 数据缓冲区的结束位置。 |
unsigned char* write_pos | 指向数据缓冲区中下次写入数据的位置。 |
unsigned char* read_pos | 指向数据缓冲区中下次读取数据存放的位置。 |
my_socket fd | 支持Perl DBI/DBD客户端接口所需的变量。包含操作系统套接字描述符的编号。 |
unsigned long max_packet | 当前网络数据包缓冲区的大小。最初设置为net-buffer-length 配置变量的值,但可能会增大以容纳更大的数据包,最大可达到max-allowed-packet 配置变量的值。 |
unsigned long max_packet_size | 此连接上允许的最大数据包大小。设置为max-allowed-packet 配置变量的值。 |
unsigned int pkt_nr | 未压缩协议的当前数据包序列号。数据包序列号主要用于协议中的完整性检查。除非存在硬件和操作系统问题,否则数据包序列号出现乱序只能是由程序错误导致的。 |
unsigned int compress_pkt_nr | 压缩协议的当前数据包序列号。 |
unsigned int write_timeout | 一次网络写入操作允许的最长时间,超过这个时间将报错超时。设置为net-write-timeout 配置变量的值。 |
unsigned int read_timeout | 一次网络读取操作允许的最长时间,超过这个时间将报错超时。设置为net-read-timeout 配置变量的值。 |
unsigned int retry_count | 网络I/O操作失败后应重试的次数,超过这个次数则认为操作失败。由于许多平台会因为一些特殊原因中断可能成功的网络I/O操作并报错,因此一次失败并不足以放弃。设置为net-retry-count 配置变量的值。 |
int fcntl | |
my_bool compress | 使用数据压缩时设置为1。 |
unsigned long remain_in_buf | 在压缩协议中,读取方尝试从套接字读取的数据可能会超过数据包的压缩长度,这样就会读取到下一个数据包的部分内容。这个变量用于跟踪多读取的字节数。当未启用压缩时,读取方在读取包头后只会尝试读取数据包的确切长度,不会读取额外的字节,所以在未压缩的情况下这个变量不会被使用。不过,这种算法对于小数据包来说效率不高。可以合理推测,未来它可能会被优化,从一开始就尝试读取更大的数据量。如果这样的话,很可能会用这个变量来跟踪读取到第一个数据包边界之后的字节数。 |
unsigned long length | 当前数据包的长度(以字节为单位),不包括包头。 |
unsigned long buf_length | 数据包缓冲区的长度。不要与数据包本身的长度混淆,例如,数据包长度不包括包头。此外,如果使用了压缩,缓冲区可能会包含下一个数据包的部分内容。 |
unsigned long where_b | read_pos - buff 的值,换句话说,就是缓冲区中当前读取位置的偏移量。 |
unsigned int *return_status | 指向与该连接相关的THD线程描述符中的server_status 变量。 |
unsigned char reading_or_writing | 没有正在进行的I/O操作时设置为0,正在进行读取操作时设置为1,正在进行写入操作时设置为2。用于处理SHOW PROCESSLIST 查询。 |
char save_char | 如果某些客户端例程可以假设数据包数据在缓冲区中的末尾之后紧接着是一个零字节,那么它们可以获得更好的性能。当使用压缩时,如果不先保存这个字节,就不能安全地将其覆盖为零。这个变量用于保存该字节,之后再恢复它。 |
my_bool no_send_ok | 大多数情况下,服务器上的成功操作会通过OK数据包报告给客户端。然而,有时并不希望这样做。如果这个变量设置为1,将不会发送OK数据包。 |
char last_error[MYSQL_ERRMSG_SIZE] char sqlstate[SQLSTATE_LENGTH+1] | 包含发送给客户端的最后一条错误消息文本的缓冲区。如果没有错误,第一个字节将设置为0。 包含ODBC和JDBC驱动程序使用的SQL状态值的缓冲区。这是4.1版本新增的。在早期版本中,驱动程序必须根据错误代码的值自行确定状态。从4.1版本开始,由服务器为它们完成这项工作。 |
unsigned int last_errno | 上次发送给客户端的错误消息中的MySQL错误代码值。如果没有错误,则设置为0。 |
unsigned char error | I/O操作成功时设置为0,协议层出现逻辑错误时设置为1,系统调用或标准库失败时设置为2,在一种特殊情况下,即尝试扩展缓冲区以容纳大数据包失败但成功跳过该大数据包时设置为3。 |
gptr query_cache_query | 用于在网络I/O代码和查询缓存之间进行适当的同步。4.0版本新增。 |
my_bool report_error my_bool return_errno | 如果应该向客户端报告错误,则设置为1。 如果应该向客户端报告MySQL错误代码值,则设置为1。在4.1版本中,这还包括报告SQL状态。 |
# TABLE结构体
TABLE结构体定义了一个数据库表描述符。表可以处于打开或关闭状态。为了在服务器中使用,它必须被打开。每当表被打开时,就会创建一个表描述符,并将其放入表缓存中,以便在后续引用同一表的请求时重复使用。
TABLE的实例经常在解析器、优化器、访问控制和查询缓存代码中被引用。它在很多方面将各个部分联系在一起。研究其成员是在一定程度上熟悉服务器底层实现细节的好方法。
这个结构体在sql/table.h
中定义为struct st_table
,然后在sql/handler.h
中通过typedef
将其别名为TABLE。
请注意,在5.1版本中,TABLE进行了重构,部分内容被移到了TABLE_SHARE
类中,同一物理表的实例之间共享TABLE_SHARE
。TABLE_SHARE
缓存在表定义缓存中。
TABLE是一个很大的结构体。我们将只介绍其最重要的部分。表3-3列出了它的一些成员。 表3-3 TABLE类的成员
成员定义 | 描述 |
---|---|
handler *file | 指向该表的存储引擎(handler)对象的指针。该对象用于所有底层数据存储和检索操作。 |
Field **field | 该表中每个字段的字段描述符数组。字段数量由fields 变量指定。 |
HASH name_hash | 用于按名称定位字段的哈希表。如果字段数量至少为MAX_FIELDS_BEFORE_HASH (目前在sql/mysql_priv.h 中定义为32),则会使用这个哈希表。 |
byte *record[2] | 一对临时缓冲区,供优化器在记录操作时使用。 |
uint fields | 表中的字段数量。 |
uint reclength | 记录的长度(以字节为单位)。请注意,这里指的是在优化器层面内存中处理记录时的长度,而不是存储引擎存储记录时的长度。 |
uint rec_buff_length | 为操作一条记录而分配的临时缓冲区的长度。 |
uint keys | 表中的键数量。 |
uint key_parts | 在MySQL术语中,作为键一部分的列称为键部分。这个变量存储键部分的数量。一个列作为几个键的一部分,就会被计数几次。 |
uint primary_key | 主键在键数组中的索引。如果存在主键,则为0,否则为MAX_KEY (在4.1及更高版本中定义为64,在4.0及更早版本中定义为32)。定义位置在sql/unireg.h 。 |
uint null_fields | 表中可以包含NULL值的字段数量。 |
uint blob_fields | 表中BLOB或TEXT类型的字段数量。 |
key_map keys_in_use | 一个映射,显示哪些键可用于查询。这包括表中所有未通过ALTER TABLE...DISABLE KEYS 或其他方式离线的键。请注意,在4.0及更早版本中,这个映射是通过简单的位掩码实现的。从4.1版本开始,key_map 成为一个对象,以满足支持大量键的需求。 |
key_map quick_keys | 可用于当前查询范围优化的键的映射。例如,如果在last_name 列上有一个键,那么SELECT * FROM phonebook WHERE last_name > 'A' AND last_name < 'B' ,如果存储引擎支持基于范围读取键,就可以进行范围优化。 |
key_map used_keys | 当前查询中可以使用的键的映射。基本上,这是在考虑查询中的FORCE KEY 和IGNORE KEY 指令进行一些过滤后,keys_in_use 的值。 |
key_map keys_in_use_for_query | 根据FORCE KEY 和IGNORE KEY 指令,可用于该查询的键的映射。 |
KEY *key_info | 表的键描述符数组。数组的长度存储在keys 变量中。 |
TYPELIB keynames | 一个查找表,用于通过键名查找键编号。 |
ha_rows max_rows | 创建表时指定的MAX_ROWS 值。这并不一定是表可以容纳的行数的硬性限制,更多的是一个提示,帮助存储引擎确定最佳的记录存储格式。 |
ha_rows min_rows | 创建表时指定的MIN_ROWS 值。目前存储在表定义文件(.frm )中,但除此之外未被使用。 |
ulong avg_row_length | 创建表时指定的AVG_ROW_LENGTH 值。这是对存储引擎的一个提示,表明在变长记录表中,一条记录的平均长度预期是多少。 |
TYPELIB fieldnames | 一个查找表,用于通过字段名查找字段编号。 |
enum db_type db_type | 该表的存储引擎类型。 |
enum row_type row_type | 指示记录是固定长度还是动态长度。 |
uint db_create_options | 创建表时设置的选项的位掩码。 |
uint db_stat | 该表的各种功能和操作的位掩码。 |
uint status | 显示最后一次记录操作状态的位掩码。它能让我们了解record 变量中的内容。 |
enum tmp_table_type tmp_table | 对于非临时表,设置为NO_TMP_TABLE ;对于非事务性临时表,设置为TMP_TABLE ;对于事务性临时表,设置为TRANSACTIONAL_TMP_TABLE 。 |
my_bool force_index | 如果在当前查询中,该表有一个通过FORCE INDEX 指令引用的索引,则设置为1。 |
my_bool key_read | 优化器使用的一个标志,用于标记在当前查询中将使用一个键从该表中检索数据。 |
my_bool db_low_byte_first | 指示该表存储引擎中整数字段的字节顺序。如果低位字节在前,则设置为1。 |
my_bool fulltext_searched | 优化器使用的一个标志,用于标记将使用全文键查找来搜索该表。 |
my_bool crashed | 如果在任何时候存储引擎报告表的内部结构已损坏,则将此标志设置为1。 |
my_bool no_keyread | 一个标志,用于通知优化器由于某些特殊情况,不应使用键从该表读取数据。 |
Field *next_number_field | 如果该字段有一个自增字段(只能有一个),则指向其描述符。否则,设置为0。 |
Field_timestamp *timestamp_field | 如果该字段有一个时间戳字段(只能有一个),则指向其描述符。否则,设置为0。 |
CHARSET_INFO *table_charset | 该表字符集的描述符。 |
MEM_ROOT mem_root | 用于表描述符各个成员的内存池。 |
GRANT_INFO grant | 该表的访问控制信息描述符。 |
char *table_cache_key | 用于在表缓存中定位该表描述符的哈希键值。它由数据库名、'\0' 、表名、'\0' 以及临时表的可选字符串连接而成。因此,table_cache_key 在代码中经常用于引用数据库名。 |
char *table_name char *real_name char *path uint key_length table_map map ulong version FILESORT_INFO sort ORDER *group ha_rows quick_rows[MAX_KEY] ulong query_id uchar frm_version THD *in_use struct st_table *next struct st_table *prev | 如果表没有别名,则与real_name 相同。否则,为别名的名称。例如,在SELECT t1.* FROM names AS t1 中,这个变量设置为t1 。表的名称。如果有别名,则为非别名名称。见 table_name 下的示例。表的 .frm 文件在文件系统中的完整路径(不包含.frm 扩展名),相对于datadir 。例如,如果表在db1 数据库中,表名为t1 ,则这个变量设置为./db1/t1 。table_cache_key 的长度(以字节为单位)。在连接操作中,每个表实例都会被分配一个编号。这个变量是一个位掩码,对应表编号的位被设置为1,其他位被清零。 用于检查内存中缓存的表是否是最新的。如果另一个线程执行 FLUSH TABLES ,则表描述符不再有效。通过将这个变量的值与全局的refresh_version 进行比较来检测这种情况。用于记录指针排序的描述符结构。在解决 GROUP BY 和ORDER BY 查询时使用。优化器通过临时表解决 GROUP BY 查询时使用。如果使用这种技术,会在临时表中创建相应的键。在这种情况下,这个字段设置为GROUP BY 表达式的描述符。范围优化器用于存储表中每个键的键范围预计匹配的记录数。 当前使用这个表描述符的查询的ID。表定义文件( .frm )格式的版本。指向当前正在使用这个表的线程的描述符。指向表链表中的 |
# Field类
Field类定义了一个字段描述符。实际上,它是为每种特定字段类型(如整数、字符串或时间戳)定义的多个子类的基抽象类。
这个类在解析器和优化器中自然起着关键作用,因为处理查询时的大多数操作都涉及表字段。
Field在sql/field.h
中定义,并在sql/field.cc
中部分实现。之所以是部分实现,是因为它是一个抽象类。它的子类(名称都以Field_
开头)完成了具体实现。
这个类的数据成员不多,但另一方面包含了许多方法。因此,我们将介绍所有的数据成员,以及最重要的一些方法。表3-4列出了Field的成员。 表3-4 Field类的成员
成员定义 | 成员描述 |
---|---|
char *ptr | 指向记录内存副本中字段数据的指针。 |
uchar *null_ptr | 指向记录内存副本中表示该字段值是否为NULL的字节的指针。 |
const char *table_name | 包含该字段的表的名称。 |
const char *field_name | 该字段的名称。 |
LEX_STRING comment | 该字段注释的内容。在定义字段时,可以在CREATE TABLE 语句中输入注释,例如CREATE TABLE t1 (n INT COMMENT'some integer value') 。 |
ulong query_id | 当前使用这个字段描述符的查询的ID。 |
key_map key_start | 如果这个位掩码的第n位被设置,则该字段是表中第n个键的第一部分。 |
key_map part_of_key | 如果这个位掩码的第n位被设置,则该字段是表中第n个键的一部分。 |
key_map part_of_sortkey | 如果这个位掩码的第n位被设置,则该字段是表中第n个键的一部分,并且该键能够按其值的升序或降序遍历。例如,对于B树键是这种情况,但对于哈希键或全文键则不是。 |
utype unireg_check | 存储在表定义文件(.frm )中的字段类型代码。 |
uint32 field_length | 该字段可存储数据的最大字节长度。 |
uint16 flags | 在CREATE TABLE 语句的字段定义中设置的字段特殊属性的位掩码,例如NOT NULL (非空)、AUTO_INCREMENT (自增)或ZEROFILL (零填充)。 |
uchar null_bit | 一个只有一位被设置的位掩码,对应记录前缀中表示该字段值为NULL的位。另见null_ptr 。 |
int store(const char *from, uint length, CHARSET_INFO *cs) | 将from 指向的字符串存储到与该字段描述符相关联的记录的内存副本中。 |
int store(double nr) | 将双精度浮点数nr 的值存储到与该字段描述符相关联的记录的内存副本中。 |
int store(longlong nr) | 将64位整数值nr 存储到与该字段描述符相关联的记录的内存副本中。 |
void store_time(TIME *ltime,timestamp_type t_type) | 将ltime 指定的时间值存储到与该字段描述符相关联的记录的内存副本中。 |
double val_real(void) | 返回与该字段描述符相关联的记录内存副本中存储的值,并将其转换为双精度浮点数。 |
String *val_str(String *str) | 返回与该字段描述符相关联的记录内存副本中存储的值,并将其转换为字符串。该值存储在参数提供的缓冲区中。请注意,调用者必须传递一个指向预先分配的String 对象的指针。如果将str 设置为0调用val_str() ,将会导致程序崩溃。 |
Item_result result_type () | 返回存储在字段中的数据类型。目前范围优化器使用该方法来决定范围优化是否合适。例如,如果a 是一个字符串,我们在a 上有一个键,并且查询是SELECT * FROM t1 WHERE a > 1 AND a < 5 ,那么如果我们有一条记录中a 等于'10' ,在('1','5') 范围内读取键将得到错误的结果。因为a 作为字符串存储,键的顺序是按字典序排列的,'10' 会落入这个范围。然而,查询的语法要求进行数值比较。所以,a 等于'10' 的记录应该被排除在外。 |
Item_result cmp_type () | 返回存储在字段中的数据类型,用于确定与其他值进行比较的方式。通常与result_type() 返回的类型相同。时间戳是一个例外,它们的result_type() 是STRING_RESULT ,而cmp_type() 是INT_RESULT 。这样可以将它们与整数按整数进行比较,而不是将整数转换为字符串再进行字符串比较。 |
void reset(void) | 清除与该字段描述符相关联的记录内存副本中设置的值。 |
bool binary() | 报告字段值的比较是否以二进制或逐字节的方式进行。例如,具有默认属性的char(N) 字段就不是这样的字段:其比较是不区分大小写的,并且会忽略尾随空格。 |
uint32 key_length() | 返回用于内存中键操作的字段长度。 |
enum_field_types type() int cmp(const char *str) | 返回表定义上下文中的字段类型。 返回 str 与和该字段描述符相关联的记录内存副本中的值的比较结果。如果字段值小于str ,返回 -1;如果相等,返回0;如果字段值大于str ,返回1。假设str 的长度为field_length 字节。 |
int key_cmp(const byte *str, uint length) | 在键的上下文中,返回str 与和该字段描述符相关联的记录内存副本中的值的比较结果。如果字段值小于str ,返回 -1;如果相等,返回0;如果字段值大于str ,返回1。 |
bool is_null(uint row_offset=0) | 如果与该字段描述符相关联的记录内存副本中的字段值在SQL意义上为NULL,则返回true 。 |
void set_null(int row_offset=0) | 将与该字段描述符相关联的记录内存副本中的字段值在SQL意义上标记为NULL。 |
bool maybe_null(void) void move_field(char *ptr arg) | 如果字段在SQL意义上可能包含NULL值,则返回true 。将内部字段数据指针重定向到不同的位置。 |
# 工具API调用
诸如内存分配、字符串操作或文件管理等许多核心工作,都是通过一组内部API调用来完成的。由于可移植性的要求,标准C库的使用非常谨慎,并且完全不使用C++库。
工具函数数量众多,本书无法一一涵盖,但我在表3 - 5中给出了一些具有代表性的示例。 表3 - 5:常见实用函数
函数原型 | 定义位置 | 描述 |
---|---|---|
gptr my_malloc(uint Size, myf MyFlags) | mysys/my_malloc.c | 对malloc() 的可移植性封装。用于为全局缓冲区和其他生命周期超过单个查询的对象,以及大内存块分配内存。 |
void my_free(gptr ptr, myf MyFlags) | mysys/my_malloc.c | 释放由my_malloc() 分配的内存块。注意,my_free() 已演变成my_no_flags_free() 的宏别名,所以你应在mysys/my_malloc.c 中查找my_no_flags_free() 的定义,而非my_free() 。尽管如此,在代码中仍使用my_free() 来释放内存块。 |
gptr my_multi_malloc(myf myFlags,...) | mysys/mulalloc.c | 为一组指针分配内存,并使每个指针指向一个大内存块的相应部分。例如:char *p1,*p2,*block; if (!(block = my_multi_malloc (MYF (MY_WME),&p1,10,&p2,20,NULL)) goto err; block 指向分配的内存块起始位置,p1 指向其中预留10字节的部分,p2 指向预留20字节的另一部分。工作完成后,应使用my_free() 释放block 。 |
void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size) | mysys/my_alloc.c | 使用mem_root 指向的描述符初始化内存池。 |
gptr alloc_root(MEM_ROOT *mem_root, unsigned int Size) | mysys/my_alloc.c | 从mem_root 指定的内存池中分配内存。返回指向分配的内存块的指针,分配失败时返回0。 |
void free_root(MEM_ROOT *mem_root, myf MyFlags) | mysys/my_alloc.c | 释放与mem_root 相关联的内存池。 |
File my_open(const char *FileName, int Flags, myf MyFlags) | mysys/my_open.c | 对open() 的封装。最后一个参数包含MySQL API特定的标志。File 类型是int 的别名。 |
int my_close(File fd, myf MyFlags) | mysys/my_open.c | 对close() 的封装。最后一个参数包含MySQL API特定的标志。 |
uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags) | mysys/my_read.c | 对read() 的功能扩展封装。若在MyFlags 中设置了MY_FULL_IO ,它会持续读取,直至成功读取完Count 字节的数据。 |
uint my_write(int Filedes, const byte *Buffer, uint Count, myf MyFlags) | mysys/my_write.c | 对write() 的功能扩展封装。会持续写入,直至写完Count 字节的数据。若MyFlags 中存在MY_WAIT_IF_FULL ,当磁盘已满时,它会等待磁盘空间可用,而非直接失败。 |
int init_io_cache(IO_CACHE *info, File file, uint cachesize, enum cache_type type, my_off_t seek_offset, pbool use_async_io, myf cache_myflags) | mysys/mf_iocache.c | 初始化I/O缓存的描述符。I/O缓存与标准C库中的FILE 结构有些相似。成功时返回0,失败时返回非零值。 |
int my_b_read(register IO_CACHE *info, byte *Buffer, uint Count) | mysys/mf_iocache.c | 从与info 相关联的I/O缓存中读取数据。从技术上讲,当缓存缓冲区中的数据不足以满足请求时,它实际上是一个预处理器宏,是_my_b_read() 函数的别名。成功时返回0,失败时返回非零值。 |
int my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count) | mysys/mf_iocache.c | 向与info 相关联的I/O缓存中写入数据。从技术上讲,当缓冲区空间不足,需要进行物理写入以满足请求时,它实际上是一个预处理器宏,是_my_b_write() 函数的别名。成功时返回0,失败时返回非零值。 |
int flush_io_cache(IO_CACHE *info) | mysys/mf_iocache.c | 将内存缓冲区中的数据写入文件描述符。注意,flush_io_cache() 实际上是my_b_flush_io_cache() 的宏别名。成功时返回0,失败时返回非零值。 |
int end_io_cache(IO_CACHE *info) | mysys/mf_iocache.c | 关闭与描述符相关联的缓存,并执行所有必要的清理操作。 |
my_string fn_format(my_string to, const char *name, const char *dir, const char *extension, uint flag) | mysys/mf_format.c | 构建文件路径,可能会调整文件扩展名。参数应以Unix风格的正斜杠格式传入。在Windows系统中,结果中的斜杠方向会相反。最后一个参数中的标志允许进行一些文件路径操作。例如,若设置了MY_RESOLVE_SYMLINKS ,写入to 参数的结果路径将解析并跟随符号链接。 |
my_bool hash_init(HASH *hash, CHARSET_INFO *charset, uint size, uint key_offset, uint key_length, hash_get_key get_key, void (*free_element)(void*)) | mysys/hash.c | 初始化哈希描述符。成功时返回0,失败时返回非零值。注意,hash_init() 实际上是_hash_init() 的宏别名。获取给定记录哈希键的方法可通过key_offset 和key_length 参数指定,也可通过函数指针get_key 指定。 |
gptr hash_search(HASH *hash, const byte *key, uint length) | mysys/hash.c | 在哈希表中查找与指定键值相关联的第一条记录。成功时返回指向该记录的指针,失败时返回0。 |
gptr hash_next(HASH *hash, const byte *key, uint length) | mysys/hash.c | 在哈希表中查找与指定键值相关联的下一条记录。在首次调用hash_search() 之后,应重复调用此函数,以检索与该键相关联的后续记录。成功时返回指向记录的指针,失败(没有更多记录)时返回0。 |
my_bool my_hash_insert(HASH *info, const byte *record) | mysys/hash.c | 将记录指针插入哈希表。成功时返回0,失败时返回非零值。过去,这个函数名为hash_insert() ,但由于命名空间冲突而被重命名。 |
my_bool hash_delete(HASH *hash, byte *record) | mysys/hash.c | 从哈希表中删除记录指针。注意,比较的是实际的指针值,而非键,并且只会删除一条记录。 |
void hash_free(HASH *hash) | mysys/hash.c | 释放与描述符相关联的哈希表,并执行所有必要的清理操作。 |
my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, uint init_alloc, uint alloc_increment) | mysys/array.c | 初始化动态数组描述符。注意,与哈希表不同,这里的操作是针对元素数据进行的,而非指针引用。因此,需要知道元素的大小。 |
my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element) | mysys/array.c | 向动态数组中插入一个元素。注意,第二个参数是一个指针,插入时数据将从该指针指向的位置复制到数组中。 |
void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx) | mysys/array.c | 将索引idx 处的元素数据复制到element 指向的地址。注意,element 必须指向一个有足够内存来容纳数组元素大小的位置。 |
void delete_dynamic(DYNAMIC_ARRAY *array) | mysys/array.c | 释放动态数组资源,并使描述符无效。在调用者使用完数组后,用于清理操作。 |
char *strmov(char *dst, const char *src) | strings/strmov.c | 类似于strcpy() ,但返回值指向dst 的新终止空字符。 |
char* strxmov(char *dst, char* src1,...) | strings/strxmov.c | 将从第二个参数到倒数第二个参数的所有内容连接到dst 中,并用空字符终止。最后一个参数必须为NullS 。返回结果的终止空字符的指针。 |
int my_snprintf(char* to, size_t n, const char* fmt,...) | strings/my_vsnprintf.c | snprintf() 的精简实现。snprintf() 是一个非常实用的函数,用于安全地将格式化字符串复制到有限长度的缓冲区中。然而,并非所有平台都支持它。my_snprintf() 还包含了标准snprintf() 实现中没有的额外功能。 |
gptr sql_alloc(uint Size) | sql/thr_malloc.cc | 从当前线程描述符的内存池中分配内存。在处理查询时,所有小内存分配都应使用此函数。注意,所有用sql_alloc() 分配的内存块在查询结束时都会被释放。既不需要也不可能单独释放用sql_alloc() 分配的内存块。如果一个内存块的使用时间较长,或者它比较大,应该使用my_malloc() 分配,并使用my_free() 释放。 |
my_string ip_to_hostname(struct in_addr *in, uint *errors) | sql/hostaname.cc | 将地址结构转换为主机的字符串表示形式,如果可能的话会进行解析。未解析的IP地址也会转换为字符串表示形式。 |
# 预处理宏
MySQL大量使用C预处理器。有一些任务,用别名来表示比在代码中完整拼写出来更合适,但又因过于简单而无需专门编写一个函数。还有一些任务,会根据编译选项的不同而采用不同的执行方式,在某些情况下甚至不会执行。这些任务通过预处理宏来完成。表3-6列出了最常用的预处理宏。 表3-6 常用预处理宏
宏 | 定义位置 | 描述 |
---|---|---|
sint2korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的有符号2字节整数。在小端序架构中,该宏仅仅是对指针的解引用操作。然而,在大端序系统中,它必须进行计算才能返回正确的值。 |
sint3korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的有符号3字节整数。 |
sint4korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的有符号4字节整数。 |
sint5korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的有符号5字节整数。 |
sint8korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的有符号8字节整数。 |
uint2korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的无符号2字节整数。 |
uint3korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的无符号3字节整数。 |
uint4korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的无符号4字节整数。 |
uint5korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的无符号5字节整数。 |
uint8korr(A) | include/my_global.h | 返回存储在位置A、低位字节在前的无符号8字节整数。 |
int2store(T, A) | include/my_global.h | 将A的值以低位字节在前的方式存储到从位置T开始的2字节中,而不考虑机器的字节序。 |
int3store(T, A) | include/my_global.h | 将A的值以低位字节在前的方式存储到从位置T开始的3字节中,而不考虑机器的字节序。 |
int4store(T, A) | include/my_global.h | 将A的值以低位字节在前的方式存储到从位置T开始的4字节中,而不考虑机器的字节序。 |
int5store(T, A) | include/my_global.h | 将A的值以低位字节在前的方式存储到从位置T开始的5字节中,而不考虑机器的字节序。 |
int8store(T, A) | include/my_global.h | 将A的值以低位字节在前的方式存储到从位置T开始的8字节中,而不考虑机器的字节序。 |
LINT_INIT(var) | include/my_global.h | 代码中的一些变量通常不进行初始化,但某些编程错误检测工具认为它们应该被初始化。为了避免一直初始化这些变量浪费CPU资源,当检测到使用了其中一个工具,或者定义了FORCE_INIT_OF_VARS时,这个宏用于对这些变量进行初始化。 |
swap_variables (t, a, b) | include/my_global.h | 交换类型为t的变量a和b的内容。 |
set_if_bigger(a, b) | include/my_global.h | 如果b大于a,则将a的值设置为b。 |
set_if_smaller(a, b) | include/my_global.h | 如果b小于a,则将a的值设置为b。 |
test_all_bits(a, b) | include/my_global.h | 如果a中设置的所有位在b中也都被设置,则返回非零值。 |
array_elements(A) | include/my_global.h | 返回数组A中的元素个数。 |
current_thd | sql/mysql_priv.h | 返回指向与当前线程相关联的THD对象的指针。 |
IF_WIN(A, B) | sql/mysql_priv.h | 在Windows和OS/2系统中展开为A,在所有其他系统中展开为B。 |
PREV_BITS (type, A) | sql/mysql_priv.h | 返回一个类型为type的位掩码,其中最低的A位被设置,其他位被清零。 |
# 全局变量
MySQL代码使用大量全局变量来实现各种目的,包括配置设置、服务器状态信息、线程间共享的各种数据结构等。研究全局变量有助于深入了解服务器架构。通常,变量的存在本身就能简洁地说明不同组件如何协同工作以及为何这样协同工作。
表3-7总结了最常用的全局变量。在5.0版本中,其中许多变量被移到了system_status_var结构体中。 表3-7 常用全局变量
变量定义 | 定义位置 | 描述 |
---|---|---|
char *mysql_data_home | sql/mysqld.cc | 指向数据目录的路径,由datadir配置参数设置。 |
char server_version[SERVER_VERSION_LENGTH] | sql/mysqld.cc | 包含在连接问候信息和日志中显示的服务器版本字符串,例如mysql - 4.1.5 - log。 |
char mysql_charsets_dir [FN_REFLEN] | sql/mysqld.cc | 包含存放字符集定义文件的配置目录路径。该值由character - sets - dir配置参数设置。 |
ulong refresh_version | sql/mysqld.cc | 每次数据库管理员发出FLUSH TABLES命令时,该值会递增。当请求使用一个已打开的表时,会将table->refresh_version的值与全局的refresh_version进行比较,以确定该表是否需要重新加载。 |
ulong thread_id | sql/mysqld.cc | 一个计数器,用于为新创建的线程分配唯一的ID值。每次创建一个新线程时,会分配当前的thread_id值,然后该值递增1。 |
ulong query_id | sql/mysqld.cc | 一个计数器,用于为新请求分配唯一的ID值。每次处理一个新请求时,会分配当前的query_id值,然后该值递增1。 |
ulong opened_tables | sql/mysqld.cc | 一个计数器,用于跟踪服务器启动以来执行了多少次表打开操作。该值在SHOW STATUS的输出中以Opened_tables显示。不要与Open_tables的值混淆,Open_tables表示当前在表缓存中的表的数量。 |
ulong created_tmp_tables | sql/mysqld.cc | 一个计数器,用于跟踪服务器启动以来创建了多少个临时表。该值在SHOW STATUS的输出中以Created_tmp_tables显示。 |
ulong created_tmp_disk_tables | sql/mysqld.cc | 在可能的情况下,MySQL会尝试将创建的临时表保存在内存中。然而,由于表的大小或内存存储引擎的限制,在某些情况下无法实现。这时,表会被创建在磁盘上,并且这个计数器会增加。这个计数器的值会显示在SHOW STATUS 的输出中Created_tmp_disk_tables 这一项。 |
ulong aborted_threads | sql/mysqld.cc | 用于跟踪成功建立连接后异常终止的连接数。该值显示在SHOW STATUS 的输出中Aborted_clients 这一项。 |
ulong aborted_connects | sql/mysqld.cc | 用于跟踪尝试连接但在身份验证阶段未能成功继续并达到能够发出请求状态的连接数。该值显示在SHOW STATUS 的输出中Aborted_connects 这一项。 |
ulong query_cache_size | sql/mysqld.cc | 从4.0版本开始新增。查询缓存的大小。由query-cache-size 配置变量设置。 |
ulong server_id | sql/mysqld.cc | 参与复制的每个服务器在其复制对等体中必须有一个唯一的ID。这个变量包含此服务器的ID值。由server-id 配置参数设置。 |
ulong max_connections | sql/mysqld.cc | 包含服务器将接受的最大同时连接数限制。由max-connections 配置变量设置。 |
ulong long_query_count | sql/mysqld.cc | 统计被优化器认为是慢查询的数量。显示在SHOW STATUS 的输出中Slow_queries 这一项。 |
ulong what_to_log | sql/mysqld.cc | 包含一个位掩码,用于指定哪些SQL命令应该被记录到服务器活动日志中。目前这是一个内部变量,用户无法设置。 |
ulong com_stat[(uint) SQLCOM_END] | sql/mysqld.cc | 一个用于统计不同类型SQL命令的计数器数组。用户可以使用SHOW STATUS LIKE 'Com_%' 查看。 |
bool abort_loop | sql/mysqld.cc | 在关机期间设置的一个标志,用于向所有循环代码区域发出信号,表明是时候退出循环了。 |
bool shutdown_in_progress | sql/mysqld.cc | 在服务器关机期间设置的一个标志。主要用于避免多次启动关机过程。 |
uint thread_count | sql/mysqld.cc | 服务器当前存在的线程总数。显示在SHOW STATUS 的输出中Threads_connected 这一项。 |
uint thread_running | sql/mysqld.cc | 当前正在处理请求的线程总数。请注意,一些现有线程可能只是在等待请求,而不是在处理请求。显示在SHOW STATUS 的输出中Threads_running 这一项。 |
MYSQL_LOG mysql_log | sql/log.cc | 与纯文本活动日志相关联的日志对象。 |
MYSQL_LOG mysql_bin_log | sql/log.cc | 与二进制更新日志相关联的日志对象。 |
MYSQL_LOG mysql_slow_log | sql/log.cc | 与慢查询日志相关联的日志对象。 |
pthread_mutex_t LOCK_open | sql/mysqld.cc | 用于保护对表缓存进行操作以及执行其他与打开表相关且需要互斥的关键区域的锁变量。 |
pthread_mutex_t LOCK_thread_count | sql/mysqld.cc | 用于保护创建或删除线程的关键区域的锁变量。 |
pthread_mutex_t LOCK_status | sql/mysqld.cc | 用于保护读取或修改通过SHOW STATUS 可见的状态变量的关键区域的锁变量。 |
pthread_cond_t COND_refresh | sql/mysqld.cc | POSIX线程广播条件变量,用于向等待线程发出信号,表明表的状态以某种方式发生了变化。 |
pthread_cond_t COND_thread_count | sql/mysqld.cc | POSIX线程广播条件变量,用于向等待线程发出信号,表明创建了一个新线程或销毁了一个旧线程。 |
I_List<THD> threads | sql/mysqld.cc | 服务器当前存在的所有线程的列表。用户可以使用SHOW PROCESSLIST 或SHOW FULL PROCESSLIST 查看更多详细信息。 |
I_List<NAMED_LIST> key_caches | sql/mysqld.cc | 从4.1版本开始新增,该版本支持MyISAM表的多个键缓存。服务器中存在的MyISAM键缓存的列表。 |
struct system_variables global_system_variables | sql/mysqld.cc | 从4.0版本开始新增。描述了客户端可以修改的服务器配置变量集合。 |
struct system_variables max_system_variables | sql/mysqld.cc | 从4.0版本开始新增。包含客户端可以修改的服务器配置变量值的限制。 |
HASH open_cache | sql/sql_base.cc | 表缓存。当打开一个表时,其描述符会被放入表缓存中。后续对打开同一个表的请求将从缓存中获取。可以使用SHOW OPEN TABLES 查看缓存内容。 |
uint protocol_version | sql/mysqld.cc | 存储网络通信协议的版本。 |
uint mysqld_port | sql/mysqld.cc | 服务器监听请求的TCP/IP端口号。 |
struct my_option my_long_options[] | sql/mysqld.cc | 描述服务器能够识别的所有配置选项。 |