internals
internals
process_alarm()
InnoDB
innodb_read_io_threads
innodb_write_io_threads
--flush_time=
val
val
mysql-test
mysql-test
--force
9306
MTR_BUILD_THREAD
shell> export MTR_BUILD_THREAD=31shell> ./mysql-test-run.pl [options
] [ test_name
]
mysql-test
test_name
internals
plugin
INSTALL PLUGIN
plugin
InnoDB
InnoDB
innodb_ft_
xxx
xxx
.doc
WITH PARSER
CREATE TABLE t ( doc CHAR(255), FULLTEXT INDEX (doc) WITH PARSER parser_name ) ENGINE=InnoDB;
ALTER TABLE t ADD FULLTEXT INDEX (doc) WITH PARSER parser_name;
WITH PARSER
FULLTEXT
DROP TABLE
MyISAM
InnoDB
INFORMATION_SCHEMA
InnoDB
INFORMATION_SCHEMA
CREATE
USER
ALTER
USER
VALIDATE_PASSWORD_STRENGTH()
mysql_parser
--log-raw
SELECT
SELECT
SELECT
Note
SHOW WARNINGS
stmt_in
stmt_out
查询” stmt_in
“重写” stmt_out
“通过查询重写插件
Rewriter
SELECT
keyring_file
INFORMATION_SCHEMA.PLUGINS
SHOW
PLUGINS
INFORMATION_SCHEMA
SHOW
VARIABLES
SHOW
STATUS
INSTALL PLUGIN
UNINSTALL PLUGIN
WITH PARSER
SHOW PLUGINS
--plugin-load
plugin_dir
--plugin_dir=
dir_name
INFORMATION_SCHEMA.PLUGINS
mysql.plugin
INSTALL
PLUGIN
mysql_options()
MYSQL_PLUGIN_DIR
include/mysql
plugin_
xxx
.h
sql
sql_plugin.cc
sql-common
client.c
SHOW STATUS
SHOW VARIABLES
libstdc++
plugin.h
#include <stdlib.h>#include <ctype.h>#include <mysql/plugin.h>
plugin.h
MySQL _宣布(_插件 name
) ... one or more server plugin descriptors here ...
MySQL _声明_插件_结局;
st_mysql_plugin
client_plugin.h
MySQL客户端插件(_宣布_ _ plugin_type
)… members common to all client plugins
…… type-specific extra members
...mysql _ _ _端客户端插件;
mysql_declare_plugin()
mysql_declare_plugin()
mysql_declare_plugin()
mysql_declare_plugin()
mysql_declare_client_plugin()
libmysqlclient
.so
auth_xxx.dylib
--plugin-load
INSTALL PLUGIN
_mysql_plugin_interface_version_
plugin.h
_mysql_plugin_declarations_
plugin.h
mysql_declare_plugin()
plugin.h
MySQL _宣布(_插件 name
) ... one or more server plugin descriptors here ...
MySQL _声明_插件_结局;
st_mysql_plugin
struct st_mysql_plugin { int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */ void *info; /* pointer to type-specific plugin descriptor */ const char *name; /* plugin name */ const char *author; /* plugin author (for I_S.PLUGINS) */ const char *descr; /* general descriptive text (for I_S.PLUGINS) */ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */ int (*init)(void *); /* the function to invoke when plugin is loaded */ int (*deinit)(void *);/* the function to invoke when plugin is unloaded */ unsigned int version; /* plugin version (for I_S.PLUGINS) */ struct st_mysql_show_var *status_vars; struct st_mysql_sys_var **system_vars; void * __reserved1; /* reserved for dependency checking */ unsigned long flags; /* flags for plugin */ };
st_mysql_plugin
type
/* The allowable types of plugins */ #define MYSQL_UDF_PLUGIN 0 /* User-defined function */ #define MYSQL_STORAGE_ENGINE_PLUGIN 1 /* Storage Engine */ #define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */ #define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */ #define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */ #define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */ #define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */ #define MYSQL_AUTHENTICATION_PLUGIN 7 /* The authentication plugin type */ ...
type
info
name
INSTALL PLUGIN
UNINSTALL PLUGIN
--plugin-load
INFORMATION_SCHEMA.PLUGINS
SHOW
PLUGINS
--socket
socket_plugin
author
desc
license
PLUGIN_LICENSE_GPL
init
INSTALL PLUGIN
deinit
UNINSTALL PLUGIN
version
INFORMATION_SCHEMA.PLUGINS
MMNN
MM
0x0302
status_vars
SHOW
STATUS
status_vars
st_mysql_show_var
system_vars
SHOW
VARIABLES
system_vars
st_mysql_sys_var
__reserved1
flags
#定义plugin_opt_no_install 1ul / * * /不可动态加载的#定义plugin_opt_no_uninstall 2ul / *不* /动态卸载
PLUGIN_OPT_NO_INSTALL
INSTALL PLUGIN
--plugin-load
UNINSTALL PLUGIN
init
simple_parser
mysql_declare_plugin(ftexample){ mysql_ftparser_plugin,/ *型* / / * * / simple_parser_descriptor,描述“simple_parser”/名字/甲骨文公司/ * * /”,作者简单的文本解析器”,/ *说明* / plugin_license_gpl,/ *插件许可*/ /*初始化函数simple_parser_plugin_init,(当加载)* / / * simple_parser_plugin_deinit,deinit功能(空载时)* / / * * /版本端口,simple_status,/ * * / simple_system_variables状态变量,系统变量/ * * /空,0 } mysql_declare_plugin_end;
MYSQL_FTPARSER_PLUGIN
FULLTEXT
plugin.h
mysql_declare_plugin_end
#ifndef MYSQL_DYNAMIC_PLUGIN#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \MYSQL_PLUGIN_EXPORT int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \MYSQL_PLUGIN_EXPORT int PSIZE= sizeof(struct st_mysql_plugin); \MYSQL_PLUGIN_EXPORT struct st_mysql_plugin DECLS[]= {#else#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {#endif#define mysql_declare_plugin(NAME) \__MYSQL_DECLARE_PLUGIN(NAME, \ builtin_ ## NAME ## _plugin_interface_version, \ builtin_ ## NAME ## _sizeof_struct_st_plugin, \ builtin_ ## NAME ## _plugin)#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
_mysql_plugin_interface_version_
-DMYSQL_DYNAMIC_PLUGIN
_mysql_plugin_interface_version_
int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); struct st_mysql_plugin _mysql_plugin_declarations_[]= { { MYSQL_FTPARSER_PLUGIN, /* type */ &simple_parser_descriptor, /* descriptor */ "simple_parser", /* name */ "Oracle Corporation", /* author */ "Simple Full-Text Parser", /* description */ PLUGIN_LICENSE_GPL, /* plugin license */ simple_parser_plugin_init, /* init function (when loaded) */ simple_parser_plugin_deinit,/* deinit function (when unloaded) */ 0x0001, /* version */ simple_status, /* status variables */ simple_system_variables, /* system variables */ NULL, 0 } ,{0,0,0,0,0,0,0,0,0,0,0,0}} };
mysql_declare_plugin()
st_mysql_plugin
mysql_declare_plugin(ftexample) { MYSQL_FTPARSER_PLUGIN, /* type */ &simple_parser_descriptor, /* descriptor */ "simple_parser", /* name */ "Oracle Corporation", /* author */ "Simple Full-Text Parser", /* description */ PLUGIN_LICENSE_GPL, /* plugin license */ simple_parser_plugin_init, /* init function (when loaded) */ simple_parser_plugin_deinit,/* deinit function (when unloaded) */ 0x0001, /* version */ simple_status, /* status variables */ simple_system_variables, /* system variables */ NULL, 0 } mysql_declare_plugin_end;
const char *simple_parser_name = "simple_parser"; const char *simple_parser_author = "Oracle Corporation"; const char *simple_parser_description = "Simple Full-Text Parser"; mysql_declare_plugin(ftexample) { MYSQL_FTPARSER_PLUGIN, /* type */ &simple_parser_descriptor, /* descriptor */ simple_parser_name, /* name */ simple_parser_author, /* author */ simple_parser_description, /* description */ PLUGIN_LICENSE_GPL, /* plugin license */ simple_parser_plugin_init, /* init function (when loaded) */ simple_parser_plugin_deinit,/* deinit function (when unloaded) */ 0x0001, /* version */ simple_status, /* status variables */ simple_system_variables, /* system variables */ NULL, 0 } mysql_declare_plugin_end;
typedef struct { const char *name; const char *author; const char *description; } plugin_info; plugin_info parser_info = { "simple_parser", "Oracle Corporation", "Simple Full-Text Parser" }; mysql_declare_plugin(ftexample) { MYSQL_FTPARSER_PLUGIN, /* type */ &simple_parser_descriptor, /* descriptor */ parser_info.name, /* name */ parser_info.author, /* author */ parser_info.description, /* description */ PLUGIN_LICENSE_GPL, /* plugin license */ simple_parser_plugin_init, /* init function (when loaded) */ simple_parser_plugin_deinit,/* deinit function (when unloaded) */ 0x0001, /* version */ simple_status, /* status variables */ simple_system_variables, /* system variables */ NULL, 0 } mysql_declare_plugin_end;
status_vars
status_vars
st_mysql_show_var
struct圣_ MySQL _是教育节目_ { char * name;char *枚举枚举值;_ MySQL _秀_型;};
type
SHOW_BOOL | |
SHOW_INT | |
SHOW_LONG | |
SHOW_LONGLONG | |
SHOW_CHAR | |
SHOW_CHAR_PTR | |
SHOW_ARRAY | st_mysql_show_var |
SHOW_FUNC | |
SHOW_DOUBLE |
SHOW_FUNC
#define SHOW_VAR_FUNC_BUFF_SIZE 1024 typedef int (*mysql_show_var_func) (void *thd, struct st_mysql_show_var *out, char *buf);
system_vars
st_mysql_sys_var
STRT St MySQL MySQL MySQL Sys Sys Le Var { int Flags;Const Char * Name,* E(* check)(thd *,斯特拉斯(* * check)(thd *,斯特拉斯(* * check)(thd *,斯特拉斯(* * Check)(Var Var Var Var * Var Var * Var Var * Var);void(* update)(thd *,斯特拉斯- MysQL Mysql Sys Var Var(Var),void *,Const Vod *);};}
name
varname
opt
PLUGIN_VAR_READONLY | |
PLUGIN_VAR_NOSYSVAR | |
PLUGIN_VAR_NOCMDOPT | |
PLUGIN_VAR_NOCMDARG | |
PLUGIN_VAR_RQCMDARG | |
PLUGIN_VAR_OPCMDARG | |
PLUGIN_VAR_MEMALLOC |
comment
check
update
default
minimum
maximum
blocksize
SYSVAR()
static int my_foo; static MYSQL_SYSVAR_INT(foo_var, my_foo, PLUGIN_VAR_RQCMDARG, "foo comment", NULL, NULL, 0, 0, INT_MAX, 0); ... SYSVAR(foo_var)= value; value= SYSVAR(foo_var); my_foo= value; value= my_foo;
THDVAR()
static MYSQL_THDVAR_BOOL(some_flag, PLUGIN_VAR_NOCMDARG, "flag comment", NULL, NULL, FALSE); ... if (THDVAR(thd, some_flag)) { do_something(); THDVAR(thd, some_flag)= FALSE; }
NULL
static struct st_mysql_sys_var *my_plugin_vars[]= { MYSQL_SYSVAR(foo_var), MYSQL_SYSVAR(some_flag), NULL};mysql_declare_plugin(fooplug){ MYSQL_..._PLUGIN, &plugin_data, "fooplug", "foo author", "This does foo!", PLUGIN_LICENSE_GPL, foo_init, foo_fini, 0x0001, NULL, my_plugin_vars, NULL, 0}mysql_declare_plugin_end;
bool
, which is a 1-byte boolean. (0 =
, 1 =true
mysql_thdvar_bool(名称、选择、点评、检查、更新,默认)mysql_sysvar_bool(名称,varname,选择、评论、检查、更新,默认)
char*
Mysql Control I Thd瓦尔Consef Str(name,OPT,comment,Check,Update,Default)MSQQL SERIN THE SYSVE INTERNATIONAL PRC(name,Varname,OPT,Comment,Check,update,Default)
int
mysql_thdvar_int(名称、选择、点评、检查、更新,默认情况下,min,max,BLK)mysql_sysvar_int(名称,varname,选择、评论、检查、更新,默认情况下,最小,最大,块大小)
unsigned int
mysql_thdvar_uint(名称、选择、点评、检查、更新,默认情况下,min,max,BLK)mysql_sysvar_uint(名称,varname,选择、评论、检查、更新,默认情况下,最小,最大,块大小)
long
mysql_thdvar_long(名称、选择、点评、检查、更新,默认情况下,min,max,BLK)mysql_sysvar_long(名称,varname,选择、评论、检查、更新,默认情况下,最小,最大,块大小)
unsigned long
mysql_thdvar_ulong(名称、选择、点评、检查、更新,默认情况下,min,max,BLK)mysql_sysvar_ulong(名称,varname,选择、评论、检查、更新,默认情况下,最小,最大,块大小)
long long
mysql_thdvar_longlong(名称、选择、点评、检查、更新,默认情况下,最小,最大,块)mysql_sysvar_longlong(名称,varname,选择、评论、检查、更新,默认情况下,最小,最大,块大小)
unsigned long long
Mysql Control I Thd瓦尔Control I Uongagong(name,OPt,Comment,Check,Update,Default,Minimum,Mimimum,Bocksize)Mysql Service Case Control Inc . Ulongong(name,Varname,opt,comment,Check,update,default,minimum,maximum,bocksize)
double
mysql_thdvar_double(名称、选择、点评、检查、更新,默认情况下,最小,最大,块)mysql_sysvar_double(名称,varname,选择、评论、检查、更新,默认情况下,最小,最大,块大小)
unsigned long
MYSQL_THDVAR_ENUM(name, opt, comment, check, update, default, typelib) MYSQL_SYSVAR_ENUM(name, varname, opt, comment, check, update, default, typelib)
unsigned long long
MYSQL_THDVAR_SET(name, opt, comment, check, update, default, typelib) MYSQL_SYSVAR_SET(name, varname, opt, comment, check, update, default, typelib)
HASH
DYNAMIC_ARRAY
argv
my_getopt.c
my.cnf
thd
st_mysql_client_plugin
struct st_mysql_client_plugin { int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(); int (*options)(const char *option, const void *); };
st_mysql_client_plugin
type
MYSQL_CLIENT_AUTHENTICATION_PLUGIN
interface_version
name
mysql_options()
--default-auth
author
desc
version
license
mysql_api
init
init
init
mysql_load_plugin()
deinit
options
st_mysql_client_plugin_AUTHENTICATION
mysql_declare_client_plugin()
mysql_declare_client_plugin(plugin_type
) ...members common to all client plugins
... ...type-specific extra members
... mysql_end_client_plugin;
type
mysql_declare_client_plugin()
plugin_type
mysql_declare_client_plugin(认证)”my_auth_plugin”、“作者姓名”,“我的客户端身份验证插件”,{1,0,0},“GPL”,空,my_auth_init,my_auth_deinit,my_auth_options,my_auth_mainmysql_end_client_plugin;
AUTHENTICATION
interface_version
MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION
my_auth_main()
mysql_options()
MYSQL_PLUGIN_DIR
char *plugin_dir = "path_to_plugin_dir
";char *default_auth = "plugin_name
“;/*…过程命令行选项。* / MySQL(MySQL和MySQL _选项,你_ _插件插件,你_);_ options(MySQL和MySQL,MySQL _ _ AUTH的违约,违约_ auth);
--plugin-dir
st_mysql_client_plugin
CMake
somepluglib.so
CMake
CMakeLists.txt
mysql_add_plugin(somepluglib somepluglib。C module_only module_output_name”somepluglib”)
CMake
-DMYSQL_DYNAMIC_PLUGIN
shell>cmake .
shell>make
CMAKE_INSTALL_PREFIX
SHOW VARIABLES
MySQL的> SHOW VARIABLES LIKE 'basedir';
变量的名字| --------------- ------------------ | _价值| --------------- ------------------ |基地| /usr/local MySQL | --------------- ------------------
plugin_dir
MySQL的> SHOW VARIABLES LIKE 'plugin_dir';
_ --------------- ----------------------------------- |变量名称|价值| --------------- -----------------------------------你|插件_ | /usr/local MySQL /图书馆/ MySQL /插件| --------------- -----------------------------------
shell> make install
MyISAM
InnoDB
simple_parser
plugin/fulltext
#include <mysql/plugin.h>
plugin.h
MYSQL_FTPARSER_PLUGIN
FULLTEXT
simple_parser
mysql_declare_plugin(ftexample){ mysql_ftparser_plugin,/ *型* / / * * / simple_parser_descriptor,描述“simple_parser”/名字/甲骨文公司/ * * /”,作者简单的文本解析器”,/ *说明* / plugin_license_gpl,/ *插件许可*/ /*初始化函数simple_parser_plugin_init,(当加载)* / / * simple_parser_plugin_deinit,deinit功能(空载时)* / / * * /版本端口,simple_status,/ * * / simple_system_variables状态变量,系统变量/ * * /空,0 } mysql_declare_plugin_end;
name
INSTALL PLUGIN
UNINSTALL PLUGIN
SHOW
PLUGINS
INFORMATION_SCHEMA.PLUGINS
st_mysql_ftparser
struct st_mysql_ftparser { int interface_version; int (*parse)(MYSQL_FTPARSER_PARAM *param); int (*init)(MYSQL_FTPARSER_PARAM *param); int (*deinit)(MYSQL_FTPARSER_PARAM *param); };
MYSQL_
xxx
_INTERFACE_VERSIONinclude/mysql/plugin_ftparser.h
init
parse
simple_parser
MYSQL_FTPARSER_INTERFACE_VERSION
static struct st_mysql_ftparser simple_parser_descriptor={ MYSQL_FTPARSER_INTERFACE_VERSION, /* interface version */ simple_parser_parse, /* parsing function */ simple_parser_init, /* parser init function */ simple_parser_deinit /* parser deinit function */};
FULLTEXT
init
MYSQL_FTPARSER_PARAM
定义st_mysql_ftparser_param { int(* mysql_parse)(结构st_mysql_ftparser_param *,char *医生,int doc_len);int(* mysql_add_word)(结构st_mysql_ftparser_param *,char*,int word_len,mysql_ftparser_boolean_info * boolean_info);void * ftparser_state;void * mysql_ftparam;结构charset_info_st * CS;char * DOC;int长度;int旗;枚举enum_ftparser_mode模式;} mysql_ftparser_param;
mysql_parse
param
参数> MySQL _ parse(参数,……);
mysql_add_word
param
参数> MySQL _添加_字(参数,……);
ftparser_state
mysql_ftparam
mysql_add_word
cs
doc
length
flags
mysql_add_word()
mysql_parse()
mode
MYSQL_FTPARSER_SIMPLE_MODE
MYSQL_FTPARSER_WITH_STOPWORDS
MYSQL_FTPARSER_FULL_BOOLEAN_INFO
MYSQL_FTPARSER_BOOLEAN_INFO
MyISAM
ft_min_word_len
ft_max_word_len
innodb_ft_min_token_size
innodb_ft_max_token_size
innodb_ft_min_token_size
innodb_ft_max_token_size
MYSQL_FTPARSER_SIMPLE_MODE
MYSQL_FTPARSER_FULL_BOOLEAN_INFO
param->mode
MYSQL_FTPARSER_BOOLEAN_INFO
定义st_mysql_ftparser_boolean_info {枚举enum_ft_token_type型;int YesNo;int weight_adjust;焦wasign;字符trunc;国际地位;/*这些解析器状态必须清除。* /焦沪指;char * quot;} mysql_ftparser_boolean_info;
type
FT_TOKEN_EOF | |
FT_TOKEN_WORD | |
FT_TOKEN_LEFT_PAREN | |
FT_TOKEN_RIGHT_PAREN | |
FT_TOKEN_STOPWORD |
yesno
weight_adjust
<
wasign
trunc
position
prev
MYSQL_FTPARSER_BOOLEAN_INFO
@distance
+
'+
apple'
'+apple'
simple_parser
静态变量simple_parser_plugin_init(void *精__attribute__((未使用))){ return(0);} static int simple_parser_plugin_deinit(void *精__attribute__((未使用))){ return(0);}
simple_parser
static int simple_parser_init(MYSQL_FTPARSER_PARAM *param __attribute__((unused))) { return(0); } static int simple_parser_deinit(MYSQL_FTPARSER_PARAM *param __attribute__((unused))) { return(0); }
simple_parser_parse()
length
static int simple_parser_parse(MYSQL_FTPARSER_PARAM *param){ char *end, *start, *docend= param->doc + param->length; for (end= start= param->doc;; end++) { if (end == docend) { if (end > start) add_word(param, start, end - start); break; } else if (isspace(*end)) { if (end > start) add_word(param, start, end - start); start= end + 1; } } return(0);}
add_word()
add_word()
static void add_word(MYSQL_FTPARSER_PARAM *param, char *word, size_t len){ MYSQL_FTPARSER_BOOLEAN_INFO bool_info= { FT_TOKEN_WORD, 0, 0, 0, 0, 0, ' ', 0 }; param->mysql_add_word(param, word, len, &bool_info);}
add_word()
st_mysql_ftparser_boolean_info
simple_parser
long number_of_calls= 0;struct st_mysql_show_var simple_status[]={ {"simple_parser_static", (char *)"just a static text", SHOW_CHAR}, {"simple_parser_called", (char *)&number_of_calls, SHOW_LONG}, {0,0,0}};
SHOW STATUS
MySQL的> SHOW STATUS LIKE 'simple_parser%';
---------------------- -------------------- | variable_name |价值| ---------------------- -------------------- | simple_parser_static |只是一个静态文本| | simple_parser_called | 0 | ---------------------- --------------------
plugin_dir
mypluglib.so
.so
安装插件simple_parser现在的mypluglib。”;
INFORMATION_SCHEMA.PLUGINS
SHOW
PLUGINS
FULLTEXT
MySQL的> CREATE TABLE t (c VARCHAR(255),
-> FULLTEXT (c) WITH PARSER simple_parser
-> ) ENGINE=MyISAM;
查询行,0行受影响(0.01秒)
mysql>INSERT INTO t VALUES
->('utf8mb4_0900_as_cs is a case-sensitive collation'),
->('I\'d like a case of oranges'),
->('this is sensitive information'),
->('another row'),
->('yet another row');
Query OK, 5 rows affected (0.02 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql>SELECT c FROM t;
+--------------------------------------------------+ | c | +--------------------------------------------------+ | utf8mb4_0900_as_cs is a case-sensitive collation | | I'd like a case of oranges | | this is sensitive information | | another row | | yet another row | +--------------------------------------------------+ 5 rows in set (0.00 sec) mysql>SELECT MATCH(c) AGAINST('case') FROM t;
+--------------------------+ | MATCH(c) AGAINST('case') | +--------------------------+ | 0 | | 1.2968142032623 | | 0 | | 0 | | 0 | +--------------------------+ 5 rows in set (0.00 sec) mysql>SELECT MATCH(c) AGAINST('sensitive') FROM t;
+-------------------------------+ | MATCH(c) AGAINST('sensitive') | +-------------------------------+ | 0 | | 0 | | 1.3253291845322 | | 0 | | 0 | +-------------------------------+ 5 rows in set (0.01 sec) mysql>SELECT MATCH(c) AGAINST('case-sensitive') FROM t;
+------------------------------------+ | MATCH(c) AGAINST('case-sensitive') | +------------------------------------+ | 1.3109166622162 | | 0 | | 0 | | 0 | | 0 | +------------------------------------+ 5 rows in set (0.01 sec) mysql>SELECT MATCH(c) AGAINST('I\'d') FROM t;
+--------------------------+ | MATCH(c) AGAINST('I\'d') | +--------------------------+ | 0 | | 1.2968142032623 | | 0 | | 0 | | 0 | +--------------------------+ 5 rows in set (0.01 sec)
plugin/daemon_example
daemon_example
#include <mysql/plugin.h>
plugin.h
daemon_example.cc
mysql_declare_plugin(daemon_example){ mysql_daemon_plugin,与daemon_example_plugin,“daemon_example”、“Brian Aker”、“守护进程实例,创建一个心跳节拍文件mysql的心跳。日志”,plugin_license_gpl,daemon_example_plugin_init,/ * * / daemon_example_plugin_deinit plugin init,/ * * /插件deinit 0x0100 / * 1 * / / *状态,空,变量* /空/ * * /系统变量为空,/ * * / 0配置选项,/* */ } mysql_declare_plugin_end旗帜;
name
INSTALL PLUGIN
UNINSTALL PLUGIN
SHOW
PLUGINS
INFORMATION_SCHEMA.PLUGINS
daemon_example_plugin
struct st_mysql_daemon daemon_example_plugin={ MYSQL_DAEMON_INTERFACE_VERSION };
daemon_example_plugin_init()
daemon_example_plugin_deinit()
plugin_dir
libdaemon_example.so
.so
_ example插件安装守护程序是libdaemon soname _ example.so;
INFORMATION_SCHEMA.PLUGINS
SHOW PLUGINS
mysql-heartbeat.log
_ example插件卸载程序;
INFORMATION_SCHEMA
InnoDB
handler/ha_innodb.cc
storage/innobase
INFORMATION_SCHEMA
#include <sql_class.h>#include <table.h>
sql
simple_i_s_table.cc
SIMPLE_I_S_TABLE
VALUE
mysql_declare_plugin(simple_i_s_library){ MYSQL_INFORMATION_SCHEMA_PLUGIN, &simple_table_info, /* type-specific descriptor */ "SIMPLE_I_S_TABLE", /* table name */ "Author Name", /* author */ "Simple INFORMATION_SCHEMA table", /* description */ PLUGIN_LICENSE_GPL, /* license type */ simple_table_init, /* init function */ NULL, 0x0100, /* version = 1.0 */ NULL, /* no status variables */ NULL, /* no system variables */ NULL, /* no reserved information */ 0 /* no flags */}mysql_declare_plugin_end;
name
INSTALL PLUGIN
UNINSTALL PLUGIN
SHOW
PLUGINS
INFORMATION_SCHEMA.PLUGINS
simple_table_info
static struct st_mysql_information_schema simple_table_info ={ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
NULL
static int table_init(void *ptr) { ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE*)ptr; schema_table->fields_info= simple_table_fields; schema_table->fill_table= simple_fill_table; return 0; }
fields_info
fill_table
fields_info
simple_table_fields
NAME
static ST_FIELD_INFO simple_table_fields[]= { {"NAME", 10, MYSQL_TYPE_STRING, 0, 0 0, 0}, {"VALUE", 6, MYSQL_TYPE_LONG, 0, MY_I_S_UNSIGNED, 0, 0}, {0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0} };
ST_FIELD_INFO
MYSQL_TYPE_
xxx
fill_table
static int simple_fill_table(THD *thd, TABLE_LIST *tables, Item *cond) { TABLE *table= tables->table; table->field[0]->store("Name 1", 6, system_charset_info); table->field[1]->store(1); if (schema_table_store_record(thd, table)) return 1; table->field[0]->store("Name 2", 6, system_charset_info); table->field[1]->store(2); if (schema_table_store_record(thd, table)) return 1; return 0; }
INFORMATION_SCHEMA
store()
store()
商店(const char*,单位长度,charset_info CS);
VALUE
store(longlong nr, bool unsigned_value);
INFORMATION_SCHEMA
sql_show.cc
plugin_dir
mysql> INSTALL PLUGIN SIMPLE_I_S_TABLE SONAME 'simple_i_s_table.so';
mysql>SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
->WHERE TABLE_NAME = 'SIMPLE_I_S_TABLE';
+------------------+ | TABLE_NAME | +------------------+ | SIMPLE_I_S_TABLE | +------------------+
mysql> SELECT * FROM INFORMATION_SCHEMA.SIMPLE_I_S_TABLE;
+--------+-------+
| NAME | VALUE |
+--------+-------+
| Name 1 | 1 |
| Name 2 | 2 |
+--------+-------+
mysql> UNINSTALL PLUGIN SIMPLE_I_S_TABLE;
plugin/semisync
rpl_semi_sync_slave
#include <mysql/plugin.h>
plugin.h
semisync_master_plugin.cc
mysql_declare_plugin(semi_sync_master) { MYSQL_REPLICATION_PLUGIN, &semi_sync_master_plugin, "rpl_semi_sync_master", "He Zhenxing", "Semi-synchronous replication master", PLUGIN_LICENSE_GPL, semi_sync_master_plugin_init, /* Plugin Init */ semi_sync_master_plugin_deinit, /* Plugin Deinit */ 0x0100 /* 1.0 */, semi_sync_master_status_vars, /* status variables */ semi_sync_master_system_vars, /* system variables */ NULL, /* config options */ 0, /* flags */ } mysql_declare_plugin_end;
semisync_slave_plugin.cc
mysql_declare_plugin(semi_sync_slave) { MYSQL_REPLICATION_PLUGIN, &semi_sync_slave_plugin, "rpl_semi_sync_slave", "He Zhenxing", "Semi-synchronous replication slave", PLUGIN_LICENSE_GPL, semi_sync_slave_plugin_init, /* Plugin Init */ semi_sync_slave_plugin_deinit, /* Plugin Deinit */ 0x0100 /* 1.0 */, semi_sync_slave_status_vars, /* status variables */ semi_sync_slave_system_vars, /* system variables */ NULL, /* config options */ 0, /* flags */ } mysql_declare_plugin_end;
semi_sync_master_plugin
struct Mysql_replication semi_sync_master_plugin= { MYSQL_REPLICATION_INTERFACE_VERSION};
static int semi_sync_master_plugin_init(void *p); static int semi_sync_master_plugin_deinit(void *p);
plugin_dir
rpl_semi_sync_slave
semisync_slave.so
plugin/audit_null
audit_null_variables.h
sql_audit.h
sql
xxx
#include <mysql/plugin_audit.h>
plugin_audit.h
plugin.h
plugin_audit.h
audit_null.c
mysql_declare_plugin(audit_null) { MYSQL_AUDIT_PLUGIN, /* type */ &audit_null_descriptor, /* descriptor */ "NULL_AUDIT", /* name */ "Oracle Corp", /* author */ "Simple NULL Audit", /* description */ PLUGIN_LICENSE_GPL, audit_null_plugin_init, /* init function (when loaded) */ audit_null_plugin_deinit, /* deinit function (when unloaded) */ 0x0003, /* version */ simple_status, /* status variables */ system_variables, /* system variables */ NULL, 0, } mysql_declare_plugin_end;
MYSQL_AUDIT_PLUGIN
audit_null_descriptor
name
INSTALL PLUGIN
UNINSTALL PLUGIN
INFORMATION_SCHEMA.PLUGINS
SHOW PLUGINS
audit_null_plugin_init
simple_status
SHOW
SHOW STATUS
SHOW VARIABLES
simple_status
xxx
Audit_null_called
system_variables
xxx
xxx
audit_null_descriptor
struct st_mysql_audit { int interface_version; void (*release_thd)(MYSQL_THD); int (*event_notify)(MYSQL_THD, mysql_event_class_t, const void *); unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; };
interface_version
interface_version
plugin_audit.h
release_thd
event_notify
class_mask
event_notify
event_notify
event_notify
event_notify function: if memory is needed to service the thread allocate memory ... rest of notification processing ... release_thd function: if memory was allocated release memory ... rest of release processing ...
NULL_AUDIT
static struct st_mysql_audit audit_null_descriptor={ MYSQL_AUDIT_INTERFACE_VERSION, /* interface version */ NULL, /* release_thd function */ audit_null_notify, /* notify function */ { (unsigned long) MYSQL_AUDIT_GENERAL_ALL, (unsigned long) MYSQL_AUDIT_CONNECTION_ALL, (unsigned long) MYSQL_AUDIT_PARSE_ALL, (unsigned long) MYSQL_AUDIT_AUTHORIZATION_ALL, (unsigned long) MYSQL_AUDIT_TABLE_ACCESS_ALL, (unsigned long) MYSQL_AUDIT_GLOBAL_VARIABLE_ALL, (unsigned long) MYSQL_AUDIT_SERVER_STARTUP_ALL, (unsigned long) MYSQL_AUDIT_SERVER_SHUTDOWN_ALL, (unsigned long) MYSQL_AUDIT_COMMAND_ALL, (unsigned long) MYSQL_AUDIT_QUERY_ALL, (unsigned long) MYSQL_AUDIT_STORED_PROGRAM_ALL }};
audit_null_notify()
class_mask
class_mask
plugin_audit.h
typedef enum{ MYSQL_AUDIT_GENERAL_CLASS = 0, MYSQL_AUDIT_CONNECTION_CLASS = 1, MYSQL_AUDIT_PARSE_CLASS = 2, MYSQL_AUDIT_AUTHORIZATION_CLASS = 3, MYSQL_AUDIT_TABLE_ACCESS_CLASS = 4, MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS = 5, MYSQL_AUDIT_SERVER_STARTUP_CLASS = 6, MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS = 7, MYSQL_AUDIT_COMMAND_CLASS = 8, MYSQL_AUDIT_QUERY_CLASS = 9, MYSQL_AUDIT_STORED_PROGRAM_CLASS = 10, /* This item must be last in the list. */ MYSQL_AUDIT_CLASS_MASK_SIZE} mysql_event_class_t;
plugin_audit.h
xxx
plugin_audit.h
typedef enum{ /** occurs after authentication phase is completed. */ MYSQL_AUDIT_CONNECTION_CONNECT = 1 << 0, /** occurs after connection is terminated. */ MYSQL_AUDIT_CONNECTION_DISCONNECT = 1 << 1, /** occurs after COM_CHANGE_USER RPC is completed. */ MYSQL_AUDIT_CONNECTION_CHANGE_USER = 1 << 2, /** occurs before authentication. */ MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE = 1 << 3} mysql_event_connection_subclass_t;#define MYSQL_AUDIT_CONNECTION_ALL (MYSQL_AUDIT_CONNECTION_CONNECT | \ MYSQL_AUDIT_CONNECTION_DISCONNECT | \ MYSQL_AUDIT_CONNECTION_CHANGE_USER | \ MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE)
NULL_AUDIT
class_mask
class_mask
MYSQL_AUDIT_CONNECTION_CONNECT | MYSQL_AUDIT_CONNECTION_CHANGE_USER
event_notify
int(* _事件通知(THD)_ MySQL,MySQL _事件_舱_ t,const void *);
event_notify
NULL_AUDIT
Audit_null_called
static int audit_null_notify(MYSQL_THD thd __attribute__((unused)), mysql_event_class_t event_class, const void *event){ ... number_of_calls++; if (event_class == MYSQL_AUDIT_GENERAL_CLASS) { const struct mysql_event_general *event_general= (const struct mysql_event_general *)event; ... } else if (event_class == MYSQL_AUDIT_CONNECTION_CLASS) { const struct mysql_event_connection *event_connection= (const struct mysql_event_connection *) event; ... } else if (event_class == MYSQL_AUDIT_PARSE_CLASS) { const struct mysql_event_parse *event_parse = (const struct mysql_event_parse *)event; ... } ...}
event
event
audit_null_notify()
else if (event_class == MYSQL_AUDIT_CONNECTION_CLASS){ const struct mysql_event_connection *event_connection= (const struct mysql_event_connection *) event; switch (event_connection->event_subclass) { case MYSQL_AUDIT_CONNECTION_CONNECT: number_of_calls_connection_connect++; break; case MYSQL_AUDIT_CONNECTION_DISCONNECT: number_of_calls_connection_disconnect++; break; case MYSQL_AUDIT_CONNECTION_CHANGE_USER: number_of_calls_connection_change_user++; break; case MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE: number_of_calls_connection_pre_authenticate++; break; default: break; }}
MYSQL_AUDIT_GENERAL_CLASS
NULL_AUDIT
my_message()
my_message(ER_AUDIT_API_ABORT, "This is my error message.", MYF(0));
my_message()
if (!thd->get_stmt_da()->is_error()) { my_message(ER_AUDIT_API_ABORT, "This is my error message.", MYF(0)); }
MYSQL_AUDIT_CONNECTION_DISCONNECT
MYSQL_AUDIT_COMMAND_END
my_message()
plugin_dir
adt_null.so
.so
安装插件null_audit现在的adt_null。”;
INFORMATION_SCHEMA.PLUGINS
SHOW PLUGINS
mysql> SHOW STATUS LIKE 'Audit_null%';
+----------------------------------------+--------+
| Variable_name | Value |
+----------------------------------------+--------+
| Audit_null_authorization_column | 0 |
| Audit_null_authorization_db | 0 |
| Audit_null_authorization_procedure | 0 |
| Audit_null_authorization_proxy | 0 |
| Audit_null_authorization_table | 0 |
| Audit_null_authorization_user | 0 |
| Audit_null_called | 185547 |
| Audit_null_command_end | 20999 |
| Audit_null_command_start | 21001 |
| Audit_null_connection_change_user | 0 |
| Audit_null_connection_connect | 5823 |
| Audit_null_connection_disconnect | 5818 |
| Audit_null_connection_pre_authenticate | 5823 |
| Audit_null_general_error | 1 |
| Audit_null_general_log | 26559 |
| Audit_null_general_result | 19922 |
| Audit_null_general_status | 21000 |
| Audit_null_global_variable_get | 0 |
| Audit_null_global_variable_set | 0 |
| Audit_null_parse_postparse | 14648 |
| Audit_null_parse_preparse | 14648 |
| Audit_null_query_nested_start | 6 |
| Audit_null_query_nested_status_end | 6 |
| Audit_null_query_start | 14648 |
| Audit_null_query_status_end | 14647 |
| Audit_null_server_shutdown | 0 |
| Audit_null_server_startup | 1 |
| Audit_null_table_access_delete | 104 |
| Audit_null_table_access_insert | 2839 |
| Audit_null_table_access_read | 97842 |
| Audit_null_table_access_update | 278 |
+----------------------------------------+--------+
Audit_null_called
SHOW STATUS
Audit_null_general_result
NULL_AUDIT
MySQL的> SHOW VARIABLES LIKE 'null_audit%';
_ name变量| ------------------------------------ ------- |空值| ------------------------------------ ------- | _ _ ABORT消息| _审计审计失败_ _ | |空值| _ | |空1阶_ _审计事件_ _检查| | |空阶_ _审计事件的| _ _ _检查1 | | _空_审计_ _事件开始| 0阶| | _审计记录事件_ _空空| | | _审计事件记录_ _ _ DEF | | ------------------------------------ -------
null_audit_event_order_check
SET null_audit_event_order_check = 'MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE;;;' 'MYSQL_AUDIT_GENERAL_LOG;;;' 'MYSQL_AUDIT_CONNECTION_CONNECT;;';
'event_name
;event_data
;command
' [';event_name
;event_data
;command
'] ...
null_audit_event_order_check
ABORT_RET
INSERT
SET null_audit_event_order_check = 'MYSQL_AUDIT_COMMAND_START;command_id="3";;' 'MYSQL_AUDIT_GENERAL_LOG;;;' 'MYSQL_AUDIT_QUERY_START;;;' 'MYSQL_AUDIT_QUERY_STATUS_END;;ABORT_RET';
ERROR 3164 (HY000): Aborted by Audit API ('MYSQL_AUDIT_QUERY_STATUS_END';1).
null_audit_abort_value
SET null_audit_abort_value = 123;
SET null_audit_abort_value = 123; SET null_audit_event_order_check = 'MYSQL_AUDIT_COMMAND_START;command_id="3";;' 'MYSQL_AUDIT_GENERAL_LOG;;;' 'MYSQL_AUDIT_QUERY_START;;ABORT_RET';
SELECT 1
错误3164(hy000):中止审核的API('mysql_audit_query_start”;123)。
null_audit_abort_message
SET null_audit_abort_message = 'Custom error text.';SET null_audit_event_order_check = 'MYSQL_AUDIT_COMMAND_START;command_id="3";;' 'MYSQL_AUDIT_GENERAL_LOG;;;' 'MYSQL_AUDIT_QUERY_START;;ABORT_RET';
ERROR 3164 (HY000): Custom error text.
null_audit_event_record_def
SET null_audit_event_record_def = 'MYSQL_AUDIT_COMMAND_START;MYSQL_AUDIT_COMMAND_END';
null_audit_event_record
UNINSTALL PLUGIN NULL_AUDIT;
mysql.user
plugin.h
client_plugin.h
plugin_auth.h
plugin_auth_common.h
#include <mysql/plugin_auth.h>
#include <mysql/plugin_auth.h> #include <mysql/client_plugin.h> #include <mysql.h>
plugin_auth.h
plugin_auth_common.h
auth_simple
auth_simple.c
.so
plugin/auth
sql-common/client.c
auth_plugin_t
auth_simple
mysql_declare_plugin(auth_simple){ MYSQL_AUTHENTICATION_PLUGIN, &auth_simple_handler, /* type-specific descriptor */ "auth_simple", /* plugin name */ "Author Name", /* author */ "Any-password authentication plugin", /* description */ PLUGIN_LICENSE_GPL, /* license type */ NULL, /* no init function */ NULL, /* no deinit function */ 0x0100, /* version = 1.0 */ NULL, /* no status variables */ NULL, /* no system variables */ NULL, /* no reserved information */ 0 /* no flags */}mysql_declare_plugin_end;
name
INSTALL PLUGIN
UNINSTALL PLUGIN
SHOW
PLUGINS
INFORMATION_SCHEMA.PLUGINS
auth_simple_handler
plugin_auth.h
结构st_mysql_auth { int interface_version;const char* client_auth_plugin;int(* authenticate_user)(mysql_plugin_vio * VIO,mysql_server_auth_info *信息);int(* generate_authentication_string)(char * outbuf,unsigned int * outbuflen,const char * inbuf,unsigned int inbuflen);int(* validate_authentication_string)(char * const inbuf,unsigned int缓冲区长度);int(* set_salt)(const char *密码,password_len unsigned int,unsigned char *盐,unsigned char * salt_len);const unsigned long authentication_flags;};
st_mysql_auth
interface_version
client_auth_plugin
authenticate_user
generate_authentication_string
validate_authentication_string
set_salt
authentication_flags
client_auth_plugin
auth_simple
static struct st_mysql_auth auth_simple_handler ={ MYSQL_AUTHENTICATION_INTERFACE_VERSION, "auth_simple", /* required client-side plugin name */ auth_simple_server /* server-side plugin main function */ generate_auth_string_hash, /* generate digest from password string */ validate_auth_string_hash, /* validate password digest */ set_salt, /* generate password salt value */ AUTH_FLAG_PRIVILEGED_USER_FOR_PASSWORD_CHANGE};
auth_simple_server()
plugin_auth.h
typedef struct st_mysql_server_auth_info { char *user_name; unsigned int user_name_length; const char *auth_string; unsigned long auth_string_length; char authenticated_as[MYSQL_USERNAME_LENGTH+1]; char external_user[512]; int password_used; const char *host_or_ip; unsigned int host_or_ip_length; } MYSQL_SERVER_AUTH_INFO;
_length
MYSQL_SERVER_AUTH_INFO
user_name
USER()
user_name_length
auth_string
mysql.user
CREATE USER 'my_user'@'localhost' IDENTIFIED WITH my_plugin AS 'my_auth_string';
my_user
'my_auth_string'
auth_string_length
authenticated_as
MYSQL_USER_NAME_LENGTH
CURRENT_USER()
external_user
external_user
password_used
password_used
host_or_ip
host_or_ip_length
auth_simple
static int auth_simple_server (MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) { unsigned char *pkt; int pkt_len; /* read the password as null-terminated string, fail on error */ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) return CR_ERROR; /* fail on empty password */ if (!pkt_len || *pkt == '\0') { info->password_used= PASSWORD_USED_NO; return CR_ERROR; } /* accept any nonempty password */ info->password_used= PASSWORD_USED_YES; return CR_OK; }
CR_OK | |
CR_OK_HANDSHAKE_COMPLETE | |
CR_ERROR | |
CR_AUTH_USER_CREDENTIALS | |
CR_AUTH_HANDSHAKE | |
CR_AUTH_PLUGIN_ERROR |
plugin/auth/dialog.c
host_cache
auth_simple_server()
info->authenticated_as
generate_authentication_string
auth_simple
generate_authentication_string
int generate_auth_string_hash(char *outbuf, unsigned int *buflen, const char *inbuf, unsigned int inbuflen){ /* fail if buffer specified by server cannot be copied to output buffer */ if (*buflen < inbuflen) return 1; /* error */ strncpy(outbuf, inbuf, inbuflen); *buflen= strlen(inbuf); return 0; /* success */}
validate_authentication_string
auth_simple
validate_authentication_string
validate_auth_string_hash(int,char *const inbuf __attribute__((未使用)),unsigned int缓冲区长度__attribute__((未使用))){ return 0;/* */ }成功
set_salt
int set_salt(const char* password __attribute__((unused)), unsigned int password_len __attribute__((unused)), unsigned char* salt __attribute__((unused)), unsigned char* salt_len) { *salt_len= 0; return 0; /* success */ }
authentication_flags
AUTH_FLAG_PRIVILEGED_USER_FOR_PASSWORD_CHANGE
CREATE USER
UPDATE
AUTH_FLAG_USES_INTERNAL_STORAGE
mysql.user
mysql_declare_client_plugin()
auth_simple
mysql_declare_client_plugin(AUTHENTICATION) "auth_simple", /* plugin name */ "Author Name", /* author */ "Any-password authentication plugin", /* description */ {1,0,0}, /* version = 1.0.0 */ "GPL", /* license type */ NULL, /* for internal use */ NULL, /* no init function */ NULL, /* no deinit function */ NULL, /* no option-handling function */ auth_simple_client /* main function */mysql_end_client_plugin;
static int auth_simple_client (MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) { int res; /* send password as null-terminated string in clear text */ res= vio->write_packet(vio, (const unsigned char *) mysql->passwd, strlen(mysql->passwd) + 1); return res ? CR_ERROR : CR_OK; }
CR_OK_HANDSHAKE_COMPLETE
plugin_dir
--plugin-load=auth_simple.so
auth_simple
MySQL的> CREATE USER 'x'@'localhost'
-> IDENTIFIED WITH auth_simple;
x
auth_simple
内核 mysql --user=x --skip-password
错误45(28000):用户访问被拒绝“X '@'本地主机'(使用密码:无)内核> mysql --user=x --password
输入密码: abc
MySQL的>
--plugin-load
DROP USER
'x'@'localhost'
mysql_options()
MYSQL_PLUGIN_DIR
char *plugin_dir = "path_to_plugin_dir
";char *default_auth = "plugin_name
“;/*…过程命令行选项。* / MySQL(MySQL和MySQL _选项,你_ _插件插件,你_);_ options(MySQL和MySQL,MySQL _ _ AUTH的违约,违约_ auth);
--plugin-dir
st_mysql_client_plugin
authenticated_as
external_user
external_user
CREATE
USER
GRANT
authenticated_as
AS
CREATE USER
CREATE USER ''@'%.example.com' IDENTIFIED WITH my_plugin AS 'extuser1=mysqlusera, extuser2=mysqluserb' CREATE USER ''@'%.example.org' IDENTIFIED WITH my_plugin AS 'extuser1=mysqluserc, extuser2=mysqluserd'
extuser2
'extuser1=mysqlusera,
extuser2=mysqluserb'
authenticated_as
example.org
'extuser1=mysqluserc, extuser2=mysqluserd'
mysqluserd
authenticated_as
auth_simple_proxy
auth_simple_proxy
authenticated_as
authenticated_as
AS
CREATE USER 'plugin_user1'@'localhost' IDENTIFIED WITH auth_simple_proxy; CREATE USER 'plugin_user2'@'localhost' IDENTIFIED WITH auth_simple_proxy AS 'proxied_user';
plugin_user2
PROXY
创建用户的proxied_user '@'本地主机'确定' proxied_user_pass”;授予代理的proxied_user '@'本地主机' ' plugin_user2 '@'本地主机';
authenticated_as
auth_simple_proxy
authenticated_as
external_user
static int auth_simple_proxy_server (MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info){ unsigned char *pkt; int pkt_len; /* read the password as null-terminated string, fail on error */ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0) return CR_ERROR; /* fail on empty password */ if (!pkt_len || *pkt == '\0') { info->password_used= PASSWORD_USED_NO; return CR_ERROR; } /* accept any nonempty password */ info->password_used= PASSWORD_USED_YES; /* if authentication string is nonempty, use as proxied user name */ /* and use client name as external_user value */ if (info->auth_string_length > 0) { strcpy (info->authenticated_as, info->auth_string); strcpy (info->external_user, info->user_name); } return CR_OK;}
USER()
CURRENT_USER()
plugin_user1
内核 mysql --user=plugin_user1 --password
输入密码: x
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user, @@external_user\G
*************************** 1. row ***************************
USER(): plugin_user1@localhost
CURRENT_USER(): plugin_user1@localhost
@@proxy_user: NULL
@@external_user: NULL
plugin_user2
内核 mysql --user=plugin_user2 --password
输入密码: x
plugin_user2
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user, @@external_user\G
*************************** 1. row ***************************
USER(): plugin_user2@localhost
CURRENT_USER(): proxied_user@localhost
@@proxy_user: 'plugin_user2'@'localhost'
@@external_user: 'plugin_user2'@'localhost'
plugin/password_validation
validate_password
validate_password
validate_password
#include <mysql/plugin_validate_password.h>
plugin_validate_password.h
plugin.h
plugin_validate_password.h
validate_password.cc
mysql_declare_plugin(validate_password) { MYSQL_VALIDATE_PASSWORD_PLUGIN, /* type */ &validate_password_descriptor, /* descriptor */ "validate_password", /* name */ "Oracle Corporation", /* author */ "check password strength", /* description */ PLUGIN_LICENSE_GPL, validate_password_init, /* init function (when loaded) */ validate_password_deinit, /* deinit function (when unloaded) */ 0x0100, /* version */ NULL, validate_password_system_variables, /* system variables */ NULL, 0, } mysql_declare_plugin_end;
name
INSTALL PLUGIN
UNINSTALL PLUGIN
INFORMATION_SCHEMA.PLUGINS
SHOW PLUGINS
validate_password_system_variables
SHOW VARIABLES
static struct st_mysql_sys_var* validate_password_system_variables[]= { MYSQL_SYSVAR(length), MYSQL_SYSVAR(number_count), MYSQL_SYSVAR(mixed_case_count), MYSQL_SYSVAR(special_char_count), MYSQL_SYSVAR(policy), MYSQL_SYSVAR(dictionary_file), NULL};
validate_password_init
validate_password_descriptor
结构st_mysql_validate_password { int interface_version;/*这个函数返回满足密码策略密码(通过插件变量选择)和虚假的所有其他密码* / int(* validate_password)(mysql_string_handle密码);/*这个函数返回密码强度(0-100)取决于政策* / int(* get_password_strength)(mysql_string_handle密码);};
interface_version
interface_version
plugin_validate_password.h
validate_password
mysql_string
string_service.cc
get_password_strength
validate_password
static struct st_mysql_validate_password validate_password_descriptor={ MYSQL_VALIDATE_PASSWORD_INTERFACE_VERSION, validate_password, /* validate function */ get_password_strength /* validate strength function */};
plugin_dir
validate_password.so
.so
1 . Plujy Plujs Valestate Industry Password Sonamine ' s Validate Artiz Pasword.so;
INFORMATION_SCHEMA.PLUGINS
SHOW PLUGINS
validate_password
MySQL的> SHOW VARIABLES LIKE 'validate_password%';
-------------------------------------- _ name变量值| -------- | | -------------------------------------- |密码验证_ -------- _字典文件| _ |验证密码长度| _ _ | 8 | |验证密码_ _混合_结婚_ count | 1 | |密码验证_ _ number _计数1 | | _密码验证| _政策中| | |特殊字符的密码验证_ _ _ _ count | -------- | 1 --------------------------------------
UNINSTALL PLUGIN validate_password;
WITH_TEST_TRACE_PLUGIN
MYSQL_TEST_TRACE_DEBUG
MYSQL_TEST_TRACE_CRASH
shell>export MYSQL_TEST_TRACE_DEBUG=1
shqll>mysql
test_trace: Test trace plugin initialized test_trace: Starting tracing in stage CONNECTING test_trace: stage: CONNECTING, event: CONNECTING test_trace: stage: CONNECTING, event: CONNECTED test_trace: stage: WAIT_FOR_INIT_PACKET, event: READ_PACKET test_trace: stage: WAIT_FOR_INIT_PACKET, event: PACKET_RECEIVED test_trace: packet received: 87 bytes 0A 35 2E 37 2E 33 2D 6D 31 33 2D 64 65 62 75 67 .5.7.3-m13-debug 2D 6C 6F 67 00 04 00 00 00 2B 7C 4F 55 3F 79 67 -log.....+|OU?yg test_trace: 004: stage: WAIT_FOR_INIT_PACKET, event: INIT_PACKET_RECEIVED test_trace: 004: stage: AUTHENTICATE, event: AUTH_PLUGIN test_trace: 004: Using authentication plugin: mysql_native_password test_trace: 004: stage: AUTHENTICATE, event: SEND_AUTH_RESPONSE test_trace: 004: sending packet: 188 bytes 85 A6 7F 00 00 00 00 01 21 00 00 00 00 00 00 00 .?......!....... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ... mysql>quit
test_trace: 008: stage: READY_FOR_COMMAND, event: SEND_COMMAND test_trace: 008: QUIT test_trace: 008: stage: READY_FOR_COMMAND, event: PACKET_SENT test_trace: 008: packet sent: 0 bytes test_trace: 008: stage: READY_FOR_COMMAND, event: DISCONNECTED test_trace: 008: Connection closed test_trace: 008: Tracing connection has ended Bye test_trace: Test trace plugin de-initialized
shell> MYSQL_TEST_TRACE_DEBUG=
WITH_TEST_TRACE_PLUGIN
simple_trace
test_trace_plugin.cc
st_mysql_client_plugin_TRACE
client_plugin.h
plugin_trace.h
#include <mysql/plugin_trace.h> #include <mysql.h>
plugin_trace.h
mysql_declare_client_plugin()
simple_trace
mysql_declare_client_plugin(TRACE) "simple_trace", /* plugin name */ "Author Name", /* author */ "Simple protocol trace plugin", /* description */ {1,0,0}, /* version = 1.0.0 */ "GPL", /* license type */ NULL, /* for internal use */ plugin_init, /* initialization function */ plugin_deinit, /* deinitialization function */ plugin_options, /* option-handling function */ trace_start, /* start-trace function */ trace_stop, /* stop-trace function */ trace_event /* event-handling function */mysql_end_client_plugin;
NULL
static int plugin_init(char *errbuf, size_t errbuf_len, int argc, va_list args) { return 0; } static int plugin_deinit() { return 0; } static int plugin_options(const char *option, const void *value) { return 0; }
trace_start()
trace_event()
static void* trace_start(struct st_mysql_client_plugin_TRACE *self, MYSQL *conn, enum protocol_stage stage) { struct st_trace_data *plugin_data= malloc(sizeof(struct st_trace_data)); fprintf(stderr, "Initializing trace: stage %d\n", stage); if (plugin_data) { memset(plugin_data, 0, sizeof(struct st_trace_data)); fprintf(stderr, "Trace initialized\n"); return plugin_data; } fprintf(stderr, "Could not initialize trace\n"); exit(1); }
trace_stop()
trace_stop()
trace_stop()
NULL
trace_stop()
静态voidtrace_stop(struct st_mysql_client_plugin_trace *自我,mysql * Conn,void * plugin_data){ fprintf(stderr,“终止微量\n”);如果(plugin_data)自由(plugin_data);}
trace_event()
NULL
static inttrace_event(struct st_mysql_client_plugin_TRACE *self, void *plugin_data, MYSQL *conn, enum protocol_stage stage, enum trace_event event, struct st_trace_event_args args){ fprintf(stderr, "Trace event received: stage %d, event %d\n", stage, event); if (event == TRACE_EVENT_DISCONNECTED) fprintf(stderr, "Connection closed\n"); return 0;}
trace_event()
trace_event()
struct st_trace_event_args { const char *plugin_name; int cmd; const unsigned char *hdr; size_t hdr_len; const unsigned char *pkt; size_t pkt_len; };
st_trace_event_args
NULL
AUTH_PLUGIN
plugin_name插件的名称
SEND_COMMAND
CMD命令codehdr指向指针的headerpkt命令包headerhdr_len长度参数的命令argumentspkt_len长度
SEND_
xxx
xxx
PKT指针或传送数据的数据长度的receivedpkt_len
PACKET_SENT
pkt_len发送的字节数
plugin_dir
LIBMYSQL_PLUGINS
shell>export LIBMYSQL_PLUGINS=simple_trace
shqll>mysql
Initializing trace: stage 0 Trace initialized Trace event received: stage 0, event 1 Trace event received: stage 0, event 2 ... Welcome to the MySQL monitor. Commands end with ; or \g. Trace event received Trace event received ... mysql>SELECT 1;
Trace event received: stage 4, event 12 Trace event received: stage 4, event 16 ... Trace event received: stage 8, event 14 Trace event received: stage 8, event 15 +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec) mysql>quit
Trace event received: stage 4, event 12 Trace event received: stage 4, event 16 Trace event received: stage 4, event 3 Connection closed Terminating trace Bye
shell> LIBMYSQL_PLUGINS=
mysql_options()
char *plugin_dir = "path_to_plugin_dir
";
/* ... process command-line options ... */
mysql_options(&mysql, MYSQL_PLUGIN_DIR, plugin_dir);
--plugin-dir
st_mysql_client_plugin
plugin/keyring
#include <mysql/plugin_keyring.h>
plugin_keyring.h
plugin.h
plugin_keyring.h
keyring.cc
mysql_declare_plugin(keyring_file) { MYSQL_KEYRING_PLUGIN, /* type */ &keyring_descriptor, /* descriptor */ "keyring_file", /* name */ "Oracle Corporation", /* author */ "store/fetch authentication data to/from a flat file", /* description */ PLUGIN_LICENSE_GPL, keyring_init, /* init function (when loaded) */ keyring_deinit, /* deinit function (when unloaded) */ 0x0100, /* version */ NULL, /* status variables */ keyring_system_variables, /* system variables */ NULL, 0, } mysql_declare_plugin_end;
name
INFORMATION_SCHEMA.PLUGINS
SHOW PLUGINS
keyring_system_variables
SHOW
VARIABLES
static struct st_mysql_sys_var *keyring_system_variables[]= { MYSQL_SYSVAR(data), NULL};
keyring_init
keyring_descriptor
struct { int」_ MySQL _ ST接口_ bool(MySQL版本;* _密钥_店)(const char * const char * _ ID密钥,密钥_ type,const char * const void *用户_ ID密钥,密钥大小_ T _ bool(Len);* _密钥_ mysql fetch)(const char * _ ID密钥,密钥_ char * const char *类型,用户ID _,void * T *的密钥,密钥大小_ _ bool(Len);* MySQL _密钥_删除)(const char * const char * _密钥ID,用户ID _ bool();MySQL _密钥生成_)*(const char * const char * _ ID密钥,密钥_ type,const char *用户_ ID密钥大小,_ _ len t);};
interface_version
interface_version
plugin_keyring.h
mysql_key_store
mysql_key_fetch
mysql_key_remove
mysql_key_generate
keyring_file
static struct st_mysql_keyring keyring_descriptor={ MYSQL_KEYRING_INTERFACE_VERSION, mysql_key_store, mysql_key_fetch, mysql_key_remove, mysql_key_generate};
mysql_key_
xxx
xxx
my_key_store
plugin_dir
keyring_file.so
keyring_file
.so
[mysqld]early-plugin-load=keyring_file.so
INFORMATION_SCHEMA.PLUGINS
SHOW PLUGINS
mysql>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE 'keyring%';
+--------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +--------------+---------------+ | keyring_file | ACTIVE | +--------------+---------------+
keyring_file
MySQL的> SHOW VARIABLES LIKE 'keyring_file%';
------------------- ---------------------------------- | variable_name |价值| ------------------- ---------------------------------- | keyring_file_data | /usr/local/ MySQL /钥匙扣/钥匙圈| ------------------- ----------------------------------
keyring_file_data
--early-plugin-load
include/mysql
plugin.h
service_
xxx
.h
get_sysvar_source
locking_service
my_plugin_log_service
status_variable_registration
my_thd_scheduler
mysql_keyring
mysql_password_policy
plugin_registry_service
plugin_registry_service
security_context
thd_alloc
thd_wait
my_snprintf
plugin.h
#include <mysql/plugin.h>
mysql/service_my_plugin_log.h
枚举plugin_log_level { my_error_level,my_warning_level,my_information_level };
my_plugin_log_message()
我的_国际_ _插件日志消息(mysql * _插件插件,插件_枚举_日志级别的教育水平,字符串格式……);
my_plugin_log_message(plugin_ptr, MY_ERROR_LEVEL, "Cannot initialize plugin");
-lmysqlservices
CMakeLists.txt
find_library(mysqlservices_lib mysqlservices路径“{ } mysql_srcdir美元/ libservices”no_default_path)
CMakeLists.txt
#插件需要误差loggingtarget_link_libraries MySQL服务库( your_plugin_library_name
mysqlservices_lib $ { })
ns1
lock1
NULL
ER_LOCKING_SERVICE_WRONG_NAME
ER_LOCKING_SERVICE_TIMEOUT
ER_LOCKING_SERVICE_DEADLOCK
ER_LOCKING_SERVICE_TIMEOUT
ER_LOCKING_SERVICE_DEADLOCK
GET_LOCK()
GET_LOCK()
#include <mysql/service_locking.h>
int mysql_acquire_locking_service_locks(MYSQL_THD opaque_thd, const char* lock_namespace, const char**lock_names, size_t lock_num, enum enum_locking_service_lock_type lock_type, unsigned long lock_timeout);
opaque_thd
lock_namespace
lock_names
lock_num
lock_type
LOCKING_SERVICE_WRITE
lock_timeout
int mysql_release_locking_service_locks(MYSQL_THD opaque_thd, const char* lock_namespace);
opaque_thd
lock_namespace
plugin_dir
.so
CREATE FUNCTION
CREATE FUNCTION service_get_read_locks RETURNS INT SONAME 'locking_service.so'; CREATE FUNCTION service_get_write_locks RETURNS INT SONAME 'locking_service.so'; CREATE FUNCTION service_release_locks RETURNS INT SONAME 'locking_service.so';
DROP
FUNCTION
拖放功能service_get_read_locks;降功能service_get_write_locks;降功能service_release_locks;
mysql> SELECT service_get_read_locks('mynamespace', 'rlock1', 'rlock2', 10);
+---------------------------------------------------------------+
| service_get_read_locks('mynamespace', 'rlock1', 'rlock2', 10) |
+---------------------------------------------------------------+
| 1 |
+---------------------------------------------------------------+
(mynamespace, rlock1)
mysql> SELECT service_get_write_locks('mynamespace', 'wlock1', 'wlock2', 10);
+----------------------------------------------------------------+
| service_get_write_locks('mynamespace', 'wlock1', 'wlock2', 10) |
+----------------------------------------------------------------+
| 1 |
+----------------------------------------------------------------+
(mynamespace, wlock1)
mysql> SELECT service_release_locks('mynamespace');
+--------------------------------------+
| service_release_locks('mynamespace') |
+--------------------------------------+
| 1 |
+--------------------------------------+
mysql> SELECT service_get_read_locks('mynamespace', '', 10);
ERROR 3131 (42000): Incorrect locking service lock name ''.
SELECT service_get_write_locks('ns', 'lock1', 'lock1', 'lock1', 0); SELECT service_get_read_locks('ns', 'lock1', 'lock1', 'lock1', 0);
metadata_locks
(ns, lock1)
service_get_write_locks()
选择service_get_write_locks('ns ',' lock1 '、' lock2,0)从T1的地方…;
INSERT INTO ... SELECT service_get_write_locks('ns', t1.col_name, 0) FROM t1;
metadata_locks
mysql>UPDATE performance_schema.setup_instruments SET ENABLED = 'YES'
->WHERE NAME = 'wait/lock/metadata/sql/mdl';
metadata_locks
MySQL的> SELECT service_get_write_locks('mynamespace', 'lock1', 0);
---------------------------------------------------- | service_get_write_locks('mynamespace ',' lock1 ',0)| ---------------------------------------------------- | 1 | ---------------------------------------------------- MySQL > SELECT service_get_read_locks('mynamespace', 'lock2', 0);
我的意思是,这是一个好的服务。 SELECT OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, LOCK_TYPE, LOCK_STATUS
-> FROM performance_schema.metadata_locks
-> WHERE OBJECT_TYPE = 'LOCKING SERVICE'\G
*************************** 1。行*************************** object_type:锁定serviceobject_schema:mynamespace object_name:lock1 lock_type:独家lock_status:授予*************************** 2。行*************************** object_type:锁定serviceobject_schema:mynamespace object_name:lock2 lock_type:共享lock_status:授予
OBJECT_TYPE
GET_LOCK()
USER
LEVEL LOCK
OBJECT_SCHEMA
LOCK_TYPE
SHARED
LOCK_STATUS
PENDING
NULL
service_get_read_locks(
namespace
,
lock_name
[,
lock_name
] ...,
timeout
)
service_get_write_locks(
namespace
,
lock_name
[,
lock_name
] ...,
timeout
)
service_release_locks(
namespace
)
service_get_read_locks()
key_id
mysql_
user_id
CURRENT_USER()
key_id
key_type
MyKey
my_key_fetch()
bool my_key_fetch(const char *key_id, const char **key_type, const char* user_id, void **key, size_t *key_len)
key_id
key_type
key
key_len
my_key_generate()
key_len
user_id
bool my_key_generate(const char *key_id, const char *key_type, const char *user_id, size_t key_len)
key_id
key_type
key_len
my_key_remove()
bool my_key_remove(const char *key_id, const char* user_id)
key_id
my_key_store()
bool my_key_store(const char *key_id, const char *key_type, const char* user_id, void *key, size_t key_len)
key_id
key_type
key
key_len
CREATE
FUNCTION
DROP
FUNCTION
ABS()
SOUNDEX()
sql/udf_example.cc
NULL
sql/udf_example.cc
mysql.h
libstdc++
metaphone
default_charset_info
man
dlopen
XXX()
extern "C" { ... }
XXX()
xxx()
DECIMAL
ROW
xxx_init()
xxx()
XXX()
REAL
NULL
xxx_deinit()
xxx()
XXX()
xxx_init()
xxx_deinit()
SUM()
xxx_clear()
xxx_add()
xxx_init()
GROUP BY
xxx_clear()
xxx_add()
xxx()
xxx_deinit()
xxx_init()
xxx()
STRING
INTEGER
REAL
CREATE FUNCTION
STRING
char *(UDF _ XXX Init initid *,* _ UDF参数字符串中,结果,unsigned大×长字符串的冰_空字符串误差);
INTEGER
大长(UDF _ xxx Init initid *,* _ UDF参数中,冰_空字符串,字符串误差);
REAL
双(UDF _ xxx Init initid *,* _ UDF参数中,冰_空字符串,字符串误差);
DECIMAL
ROW
bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);
initid
UDF_INIT
bool maybe_null
xxx_init()
1
NULL
maybe_null
unsigned int decimals
1.34
1.3
decimals
DECIMAL
FLOAT
DOUBLE
mysql_com.h
decimals
FLOAT
DOUBLE
FLOAT
1345E-3
decimals
decimals
unsigned int max_length
max_length
max_length
char *ptr
initid->ptr
initid->ptr = allocated_memory;
xxx()
initid->ptr
bool const_item
xxx_init()
1
0
xxx_reset()
UDF_ARGS
void xxx_reset(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
xxx_reset()
xxx_reset()
xxx_reset()
xxx_add()
xxx_clear()
xxx_clear()
暴力_(UDF)xxx Init _ initid char * *,冰_空字符串误差);
is_null
xxx_clear()
error
xxx_clear()
xxx_add()
UDF_ARGS
暴力_ add(xxx Init initid UDF _ *,* _ UDF参数中,冰_空字符串,字符串误差);
xxx()
xxx()
xxx()
xxx_reset()
UDF_ARGS
is_null
xxx_reset()
xxx_add()
xxx()
*error
*is_null
*error
*is_null
xxx()
args
unsigned int arg_count
if (args->arg_count != 2) { strcpy(message,"XXX() requires two arguments"); return 1; }
UDF_ARGS
enum Item_result *arg_type
STRING_RESULT
REAL_RESULT
arg_type
if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT){ strcpy(message,"XXX() requires a string and an integer"); return 1;}
DECIMAL_RESULT
arg_type
xxx_init()
args->arg_type[0] = STRING_RESULT;args->arg_type[1] = INT_RESULT;
1.3
DECIMAL
REAL_RESULT
args->arg_type[2] = REAL_RESULT;
char **args
args->args
args->args[i]
0
4*7-2
SIN(3.14)
args->args
i
args->args[i]
STRING_RESULT
args->lengths[i]
INT_RESULT
long long
long long int_val;int_val = *((long long*) args->args[i]);
REAL_RESULT
double
double real_val;real_val = *((double*) args->args[i]);
DECIMAL_RESULT
ROW_RESULT
unsigned long *lengths
lengths
INT_RESULT
lengths
char *maybe_null
maybe_null
char **attributes
args->attributes
args->attributes[i]
[AS]
alias_name
alias_name
my_udf()
我的_ UDF(expr1的选择,你alias1 expr2,expr3 alias2);
attributes
args->attributes[0] = "expr1" args->attribute_lengths[0] = 5 args->attributes[1] = "alias1" args->attribute_lengths[1] = 6 args->attributes[2] = "alias2" args->attribute_lengths[2] = 6
unsigned long *attribute_lengths
attribute_lengths
0
xxx_init()
MYSQL_ERRMSG_SIZE
xxx()
double
memcpy(result, "result string", 13); *length = 13;
xxx()
xxx()
malloc()
xxx()
ptr
xxx()
NULL
1
*is_null = 1;
*error
*error = 1;
xxx()
1
XXX()
sql/udf_example.cc
udf_example.cc
metaphon()
myfunc_double()
myfunc_int()
sequence([const int])
lookup()
reverse_lookup()
avgcost()
shell> gcc -shared -o udf_example.so udf_example.cc
udf_example.so
内核 make udf_example
udf_example.cc
udf_example.so
plugin_dir
lib
libudf_example.so
sql
udf_example.cc
makefile
PROJECT(udf_example) # Path for MySQL include directory INCLUDE_DIRECTORIES("c:/mysql/include") ADD_DEFINITIONS("-DHAVE_DLOPEN") ADD_LIBRARY(udf_example MODULE udf_example.cc udf_example.def) TARGET_LINK_LIBRARIES(udf_example wsock32)
cmake -G "<Generator>"
udf_example.dll
中udf_example.sln /版本发布
.so
mysql>CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
mysql>CREATE FUNCTION myfunc_double RETURNS REAL SONAME 'udf_example.so';
mysql>CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME 'udf_example.so';
mysql>CREATE FUNCTION sequence RETURNS INTEGER SONAME 'udf_example.so';
mysql>CREATE FUNCTION lookup RETURNS STRING SONAME 'udf_example.so';
mysql>CREATE FUNCTION reverse_lookup
->RETURNS STRING SONAME 'udf_example.so';
mysql>CREATE AGGREGATE FUNCTION avgcost
->RETURNS REAL SONAME 'udf_example.so';
DROP
FUNCTION
MySQL的> DROP FUNCTION metaphon;
MySQL的> DROP FUNCTION myfunc_double;
MySQL的> DROP FUNCTION myfunc_int;
MySQL的> DROP FUNCTION sequence;
MySQL的> DROP FUNCTION lookup;
MySQL的> DROP FUNCTION reverse_lookup;
MySQL的> DROP FUNCTION avgcost;
CREATE FUNCTION
DROP FUNCTION
mysql
INSERT
DELETE
CREATE
FUNCTION
DROP FUNCTION
CREATE
FUNCTION
CREATE FUNCTION
DROP FUNCTION
--skip-grant-tables
plugin_dir
CREATE FUNCTION
DROP FUNCTION
INSERT
DELETE
mysql.func
xxx
xxx_init()
xxx_reset()
xxx_add()
--allow-suspicious-udfs
xxx
--allow-suspicious-udfs
sql
item_create.cc
Create_func_arg0
Create_func_arg2
Create_func_uuid
Create_func_pow
Create_native_func
item_create.cc
静态native_func_registry func_array [ ]
"LCASE"
Create_func_lcase
item_func.h
Item_str_func
item_func.cc
双_ Item函数的名称:_ VAL()函数的_ _隆龙item的名称:_:val(int *)_ item字符串的名称:_函数str():string str)
Item_num_func
val()
::str()
current_thd->lex->safe_to_cache_query=0;
void Item_func_newname::fix_length_and_dec()
max_length
maybe_null = 0
NULL
Item_func_mod::fix_length_and_dec
NULL
::val_int()
null_value
::str()
String *str
sql_string.h
::str()
NULL
mysys/thr_lock
--skip-new
my.cnf
OPTIMIZE TABLE
EXPLAIN
-DWITH_DEBUG=1
--debug
-DWITH_DEBUG=1
CMAKE_C_FLAGS
CMAKE_CXX_FLAGS
-DWITH_DEBUG=1
stderr
mysqld.exe
mysqld -V
/tmp/mysqld.trace
shell> mysqld --debug
--standalone
C:\> mysqld-debug --debug --standalone
mysql.exe
mysqld --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace
pdb
mysqld
.exe
mysqld.dmp
core-file
c:\symbols
dir /s /b windbg.exe
windbg.exe
mysqld.pdb
windbg.exe -i "C:\mysql-8.0.14-winx64\bin\"^
-z "C:\mysql-8.0.14-winx64\data\mysqld.dmp"^
-srcpath "E:\ade\mysql_archives\8.0\8.0.14\mysql-8.0.14"^
-y "C:\mysql-8.0.14-winx64\bin;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols"^
-v -n -c "!analyze -vvvvv"
^
run --one-thread
LD_ASSUME_KERNEL=2.4.1 export LD_ASSUME_KERNEL
--skip-stack-trace
--gdb
SIGINT
^C
thread_cache_size
max_connections
--thread_cache_size=5'
--core-file
shell> gdb mysqld core
gdb> backtrace full
gdb> quit
.gdb
设置打印sevenbit offhandle SIGUSR1不停不停不停的noprinthandle SIGUSR2 noprinthandle sigwaiting noprinthandle siglwp不停的noprinthandle sigpipe nostophandle SIGALRM信号nostophandle SIGHUP nostophandle SIGTERM路思拓NOPRINT
shell> gdb /usr/local/libexec/mysqld
gdb> run
...
backtrace full # Do this when mysqld crashes
strace
strace /tmp/log libexec/mysqld
DBI
DBI_TRACE
-fomit-frame-pointer
mysqld got signal 11; Attempting backtrace. You can use the following information to find out where mysqld died. If you see no messages after this, something went terribly wrong... stack_bottom = 0x41fd0110 thread_stack 0x40000 mysqld(my_print_stacktrace+0x32)[0x9da402] mysqld(handle_segfault+0x28a)[0x6648e9] /lib/libpthread.so.0[0x7f1a5af000f0] /lib/libc.so.6(strcmp+0x2)[0x7f1a5a10f0f2] mysqld(_Z21check_change_passwordP3THDPKcS2_Pcj+0x7c)[0x7412cb] mysqld(_ZN16set_var_password5checkEP3THD+0xd0)[0x688354] mysqld(_Z17sql_set_variablesP3THDP4ListI12set_var_baseE+0x68)[0x688494] mysqld(_Z21mysql_execute_commandP3THD+0x41a0)[0x67a170] mysqld(_Z11mysql_parseP3THDPKcjPS2_+0x282)[0x67f0ad] mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0xbb7[0x67fdf8] mysqld(_Z10do_commandP3THD+0x24d)[0x6811b6] mysqld(handle_one_connection+0x11c)[0x66e05e]
mysqld got signal 11; Attempting backtrace. You can use the following information to find out where mysqld died. If you see no messages after this, something went terribly wrong... stack_bottom = 0x41fd0110 thread_stack 0x40000 [0x9da402] [0x6648e9] [0x7f1a5af000f0] [0x7f1a5a10f0f2] [0x7412cb] [0x688354] [0x688494] [0x67a170] [0x67f0ad] [0x67fdf8] [0x6811b6] [0x66e05e]
mysqld.stack
0x9da4020x6648e90x7f1a5af000f00x7f1a5a10f0f20x7412cb0x6883540x6884940x67a1700x67f0ad0x67fdf80x6811b60x66e05e
shell> nm -n libexec/mysqld > /tmp/mysqld.sym
shell> nm -D -n libexec/mysqld > /tmp/mysqld.sym
--demangle
shell> resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack
shell> resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack | c++filt
glibc
plugin/auth/auth_test_plugin.so(+0x9a6)[0x7ff4d11c29a6]
+0x9a6
内核 addr2line -fie auth_test_plugin.so 0x9a6
auth_test_pluginmysql-trunk /插件/认证/ test_plugin。C:65
binutils
printstack()
插件/认证/ auth_test_plugin。所以:0x1510
shell> gaddr2line -fie auth_test_plugin.so 0x1510
mysql-trunk/plugin/auth/test_plugin.c:88
000007FEF07E10A4 auth_test_plugin.dll!auth_test_plugin()[test_plugin.c:72]
host_name
.log
EXPLAIN
SELECT
mysqld restarted
host_name
mysql
--myisam-recover-options
hostname.err
Warning: Repairing table
MyISAM
Got an error from thread_id=1, mi_dynrec.c:368
Checking table...
MyISAM
MyISAM
table
hostname-bin.
NNNNNN
-DWITH_DEBUG=1
MYSQL_DEBUG
内核 MYSQL_DEBUG=d:t:O,/tmp/client.trace
内核 export MYSQL_DEBUG
/tmp/client.trace
shell> mysql --debug=d:t:O,/tmp/client.trace
mysql.h
dbug
--debug[=
debug_options
]debug_options
-#
debug_options
d:t:i:O,\mysqld.trace
d
t
i
o,/tmp/mysqld.trace
debug_options
program_name
--debug=d:t --debug=d:f,main,subr1:F:L:t,20 --debug=d,input,output,files:n --debug=d:t:i:O,\\mysqld.trace
debug
MySQL的> SET GLOBAL debug = '
debug_options
';MySQL的> SET SESSION debug = '
debug_options
';
SYSTEM_VARIABLES_ADMIN
SUPER
debug_options
field_1:field_2:…:field_ N
+
[+|-]flag[,modifier,modifier,...,modifier]
|
|
|
|
|
|
| |
| |
| |
| |
| |
|
|
|
|
|
|
| |
| |
|
|
|
+
d
+
+
d
d
MySQL的> SET debug = 'd';
MySQL的> SELECT @@debug;
--------- | @ @调试| --------- | D>| --------- MySQL SET debug = 'd,error,warning';
MySQL的> SELECT @@debug;
----------------- | @ @调试| ----------------- | D、错误、警告| -----------------
+
d
MySQL的> SET debug = '+d,loop';
MySQL的> SELECT @@debug;
---------------------- | @ @调试| ---------------------- | D、错误、警告、环| ---------------------- MySQL > SET debug = '-d,error,loop';
MySQL的> SELECT @@debug;
----------- | @ @调试| ----------- | D,警告| -----------
mysql>SET debug = 'd';
mysql>SELECT @@debug;
+---------+ | @@debug | +---------+ | d | +---------+ mysql>SET debug = '+d,loop';
mysql>SELECT @@debug;
+---------+ | @@debug | +---------+ | d | +---------+
d
MySQL的> SET debug = 'd,error,loop';
MySQL的> SELECT @@debug;
-------------- | @ @调试| -------------- | D、错误、环| -------------- MySQL > SET debug = '-d,error,loop';
MySQL的> SELECT @@debug;
--------- | @ @调试| --------- | | ---------