internalsinternals
process_alarm()
InnoDBinnodb_read_io_threadsinnodb_write_io_threads
--flush_time=valval
mysql-testmysql-test
--force
9306MTR_BUILD_THREAD
shell> export MTR_BUILD_THREAD=31shell> ./mysql-test-run.pl [options] [ test_name]
mysql-testtest_name
internals
pluginINSTALL PLUGINplugin
InnoDB
InnoDB
innodb_ft_xxxxxx
.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
FULLTEXTDROP TABLE
MyISAMInnoDB
INFORMATION_SCHEMAInnoDB
INFORMATION_SCHEMA
CREATE
USERALTER
USER
VALIDATE_PASSWORD_STRENGTH()
mysql_parser
--log-raw
SELECTSELECTSELECT
NoteSHOW WARNINGSstmt_instmt_out
查询” stmt_in“重写” stmt_out“通过查询重写插件
RewriterSELECT
keyring_file
INFORMATION_SCHEMA.PLUGINSSHOW
PLUGINS
INFORMATION_SCHEMA
SHOW
VARIABLESSHOW
STATUS
INSTALL PLUGIN
UNINSTALL PLUGIN
WITH PARSER
SHOW PLUGINS
--plugin-load
plugin_dir--plugin_dir=dir_name
INFORMATION_SCHEMA.PLUGINS
mysql.pluginINSTALL
PLUGIN
mysql_options()MYSQL_PLUGIN_DIR
include/mysqlplugin_xxx.h
sqlsql_plugin.cc
sql-commonclient.c
SHOW STATUSSHOW 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.soauth_xxx.dylib
--plugin-loadINSTALL 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
nameINSTALL PLUGINUNINSTALL PLUGIN--plugin-loadINFORMATION_SCHEMA.PLUGINSSHOW
PLUGINS
--socketsocket_plugin
author
desc
licensePLUGIN_LICENSE_GPL
initINSTALL PLUGIN
deinitUNINSTALL PLUGIN
versionINFORMATION_SCHEMA.PLUGINSMMNNMM0x0302
status_varsSHOW
STATUS
status_varsst_mysql_show_var
system_varsSHOW
VARIABLES
system_varsst_mysql_sys_var
__reserved1
flags
#定义plugin_opt_no_install 1ul / * * /不可动态加载的#定义plugin_opt_no_uninstall 2ul / *不* /动态卸载
PLUGIN_OPT_NO_INSTALLINSTALL PLUGIN--plugin-loadUNINSTALL 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_PLUGINFULLTEXT
plugin.hmysql_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_varsst_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_varsst_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
argvmy_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
typeMYSQL_CLIENT_AUTHENTICATION_PLUGIN
interface_version
namemysql_options()--default-auth
author
desc
version
license
mysql_api
init
initinitmysql_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;
typemysql_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;
AUTHENTICATIONinterface_versionMYSQL_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
CMakesomepluglib.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_PREFIXSHOW VARIABLES
MySQL的> SHOW VARIABLES LIKE 'basedir';变量的名字| --------------- ------------------ | _价值| --------------- ------------------ |基地| /usr/local MySQL | --------------- ------------------
plugin_dir
MySQL的> SHOW VARIABLES LIKE 'plugin_dir';_ --------------- ----------------------------------- |变量名称|价值| --------------- -----------------------------------你|插件_ | /usr/local MySQL /图书馆/ MySQL /插件| --------------- -----------------------------------
shell> make install
MyISAMInnoDB
simple_parser
plugin/fulltext
#include <mysql/plugin.h>
plugin.h
MYSQL_FTPARSER_PLUGINFULLTEXT
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;
nameINSTALL PLUGINUNINSTALL PLUGINSHOW
PLUGINSINFORMATION_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
initparse
simple_parserMYSQL_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_ftparammysql_add_word
cs
doc
length
flagsmysql_add_word()
mysql_parse()
mode
MYSQL_FTPARSER_SIMPLE_MODE
MYSQL_FTPARSER_WITH_STOPWORDS
MYSQL_FTPARSER_FULL_BOOLEAN_INFOMYSQL_FTPARSER_BOOLEAN_INFO
MyISAMft_min_word_lenft_max_word_leninnodb_ft_min_token_sizeinnodb_ft_max_token_sizeinnodb_ft_min_token_sizeinnodb_ft_max_token_sizeMYSQL_FTPARSER_SIMPLE_MODEMYSQL_FTPARSER_FULL_BOOLEAN_INFO
param->modeMYSQL_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
prevMYSQL_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_dirmypluglib.so
.so
安装插件simple_parser现在的mypluglib。”;
INFORMATION_SCHEMA.PLUGINSSHOW
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_exampledaemon_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旗帜;
nameINSTALL PLUGINUNINSTALL PLUGINSHOW
PLUGINSINFORMATION_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_dirlibdaemon_example.so
.so
_ example插件安装守护程序是libdaemon soname _ example.so;
INFORMATION_SCHEMA.PLUGINSSHOW PLUGINS
mysql-heartbeat.log
_ example插件卸载程序;
INFORMATION_SCHEMAInnoDBhandler/ha_innodb.ccstorage/innobase
INFORMATION_SCHEMA
#include <sql_class.h>#include <table.h>
sql
simple_i_s_table.ccSIMPLE_I_S_TABLEVALUE
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;nameINSTALL PLUGINUNINSTALL PLUGINSHOW
PLUGINSINFORMATION_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_infosimple_table_fieldsNAME
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_INFOMYSQL_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_SCHEMAstore()store()
商店(const char*,单位长度,charset_info CS);
VALUE
store(longlong nr, bool unsigned_value);
INFORMATION_SCHEMAsql_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/semisyncrpl_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_dirrpl_semi_sync_slavesemisync_slave.so
plugin/audit_nullaudit_null_variables.h
sql_audit.hsqlxxx
#include <mysql/plugin_audit.h>
plugin_audit.hplugin.hplugin_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
nameINSTALL PLUGINUNINSTALL PLUGININFORMATION_SCHEMA.PLUGINSSHOW PLUGINS
audit_null_plugin_init
simple_statusSHOWSHOW STATUSSHOW VARIABLES
simple_statusxxxAudit_null_called
system_variablesxxxxxx
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_versioninterface_versionplugin_audit.h
release_thd
event_notify
class_mask
event_notifyevent_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_maskplugin_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.hxxxplugin_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_AUDITclass_maskclass_mask
MYSQL_AUDIT_CONNECTION_CONNECT | MYSQL_AUDIT_CONNECTION_CHANGE_USER
event_notify
int(* _事件通知(THD)_ MySQL,MySQL _事件_舱_ t,const void *);
event_notify
NULL_AUDITAudit_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; ... } ...}eventeventaudit_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_diradt_null.so
.so
安装插件null_audit现在的adt_null。”;
INFORMATION_SCHEMA.PLUGINSSHOW 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_calledSHOW STATUSAudit_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_RETINSERT
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.hplugin_auth_common.h
auth_simpleauth_simple.c.so
plugin/authsql-common/client.cauth_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;nameINSTALL PLUGINUNINSTALL PLUGINSHOW
PLUGINSINFORMATION_SCHEMA.PLUGINS
auth_simple_handlerplugin_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_nameUSER()
user_name_length
auth_stringmysql.user
CREATE USER 'my_user'@'localhost' IDENTIFIED WITH my_plugin AS 'my_auth_string';
my_user'my_auth_string'
auth_string_length
authenticated_asMYSQL_USER_NAME_LENGTHCURRENT_USER()
external_userexternal_user
password_usedpassword_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_simplegenerate_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_simplevalidate_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_CHANGECREATE USERUPDATE
AUTH_FLAG_USES_INTERNAL_STORAGEmysql.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;
xauth_simple
内核 mysql --user=x --skip-password错误45(28000):用户访问被拒绝“X '@'本地主机'(使用密码:无)内核> mysql --user=x --password输入密码: abcMySQL的>
--plugin-loadDROP 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_asexternal_userexternal_user
CREATE
USERGRANT
authenticated_as
ASCREATE 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_asexample.org'extuser1=mysqluserc, extuser2=mysqluserd'mysqluserd
authenticated_as
auth_simple_proxyauth_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_user2PROXY
创建用户的proxied_user '@'本地主机'确定' proxied_user_pass”;授予代理的proxied_user '@'本地主机' ' plugin_user2 '@'本地主机';
authenticated_asauth_simple_proxyauthenticated_asexternal_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_validationvalidate_password
validate_passwordvalidate_password
#include <mysql/plugin_validate_password.h>
plugin_validate_password.hplugin.hplugin_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;
nameINSTALL PLUGINUNINSTALL PLUGININFORMATION_SCHEMA.PLUGINSSHOW PLUGINS
validate_password_system_variablesSHOW 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_versioninterface_versionplugin_validate_password.h
validate_passwordmysql_stringstring_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_dirvalidate_password.so
.so
1 . Plujy Plujs Valestate Industry Password Sonamine ' s Validate Artiz Pasword.so;
INFORMATION_SCHEMA.PLUGINSSHOW 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=1shqll>mysqltest_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>quittest_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_tracetest_trace_plugin.ccst_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()NULLtrace_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_argsNULL
AUTH_PLUGIN
plugin_name插件的名称
SEND_COMMAND
CMD命令codehdr指向指针的headerpkt命令包headerhdr_len长度参数的命令argumentspkt_len长度
SEND_xxxxxx
PKT指针或传送数据的数据长度的receivedpkt_len
PACKET_SENT
pkt_len发送的字节数
plugin_dir
LIBMYSQL_PLUGINS
shell>export LIBMYSQL_PLUGINS=simple_traceshqll>mysqlInitializing 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>quitTrace 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.hplugin.hplugin_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;
nameINFORMATION_SCHEMA.PLUGINSSHOW PLUGINS
keyring_system_variablesSHOW
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_versioninterface_versionplugin_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_xxxxxxmy_key_store
plugin_dirkeyring_file.so
keyring_file.so
[mysqld]early-plugin-load=keyring_file.so
INFORMATION_SCHEMA.PLUGINSSHOW PLUGINS
mysql>SELECT PLUGIN_NAME, PLUGIN_STATUSFROM INFORMATION_SCHEMA.PLUGINSWHERE 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_serviceplugin_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");
-lmysqlservicesCMakeLists.txt
find_library(mysqlservices_lib mysqlservices路径“{ } mysql_srcdir美元/ libservices”no_default_path)
CMakeLists.txt
#插件需要误差loggingtarget_link_libraries MySQL服务库( your_plugin_library_namemysqlservices_lib $ { })
ns1lock1
NULLER_LOCKING_SERVICE_WRONG_NAME
ER_LOCKING_SERVICE_TIMEOUT
ER_LOCKING_SERVICE_DEADLOCK
ER_LOCKING_SERVICE_TIMEOUTER_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_typeLOCKING_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_TYPEGET_LOCK()USER
LEVEL LOCK
OBJECT_SCHEMALOCK_TYPESHARED
LOCK_STATUSPENDING
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_idmysql_
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_lenuser_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
FUNCTIONDROP
FUNCTION
ABS()SOUNDEX()
sql/udf_example.cc
NULL
sql/udf_example.ccmysql.h
libstdc++
metaphonedefault_charset_infoman
dlopen
XXX()
extern "C" { ... }
XXX()
xxx()
DECIMALROW
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()STRINGINTEGERREALCREATE FUNCTION
STRING
char *(UDF _ XXX Init initid *,* _ UDF参数字符串中,结果,unsigned大×长字符串的冰_空字符串误差);
INTEGER
大长(UDF _ xxx Init initid *,* _ UDF参数中,冰_空字符串,字符串误差);
REAL
双(UDF _ xxx Init initid *,* _ UDF参数中,冰_空字符串,字符串误差);
DECIMALROW
bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);
initidUDF_INIT
bool maybe_null
xxx_init()1NULLmaybe_null
unsigned int decimals
1.341.3
decimalsDECIMALFLOATDOUBLEmysql_com.h
decimalsFLOATDOUBLEFLOAT1345E-3
decimalsdecimals
unsigned int max_length
max_length
max_length
char *ptr
initid->ptr
initid->ptr = allocated_memory;
xxx()initid->ptr
bool const_item
xxx_init()10
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_nullxxx_clear()
error
xxx_clear()
xxx_add()
UDF_ARGS
暴力_ add(xxx Init initid UDF _ *,* _ UDF参数中,冰_空字符串,字符串误差);
xxx()
xxx()
xxx()
xxx_reset()UDF_ARGS
is_nullxxx_reset()xxx_add()xxx()*error
*is_null*error
*is_nullxxx()
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_RESULTREAL_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_typexxx_init()
args->arg_type[0] = STRING_RESULT;args->arg_type[1] = INT_RESULT;
1.3DECIMALREAL_RESULT
args->arg_type[2] = REAL_RESULT;
char **args
args->argsargs->args[i]04*7-2SIN(3.14)
args->args
iargs->args[i]
STRING_RESULTargs->lengths[i]
INT_RESULTlong long
long long int_val;int_val = *((long long*) args->args[i]);
REAL_RESULTdouble
double real_val;real_val = *((double*) args->args[i]);
DECIMAL_RESULT
ROW_RESULT
unsigned long *lengths
lengthsINT_RESULTlengths
char *maybe_null
maybe_null
char **attributes
args->attributesargs->attributes[i]
[AS]
alias_namealias_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
0xxx_init()MYSQL_ERRMSG_SIZE
xxx()double
memcpy(result, "result string", 13); *length = 13;
xxx()xxx()
malloc()xxx()ptrxxx()
NULL1
*is_null = 1;
*error
*error = 1;
xxx()1XXX()
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.ccudf_example.soplugin_dir
liblibudf_example.so
sqludf_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 FUNCTIONDROP FUNCTIONmysqlINSERTDELETE
CREATE
FUNCTIONDROP FUNCTIONCREATE
FUNCTION
CREATE FUNCTIONDROP FUNCTION--skip-grant-tables
plugin_dir
CREATE FUNCTIONDROP FUNCTIONINSERTDELETEmysql.func
xxxxxx_init()xxx_reset()xxx_add()--allow-suspicious-udfsxxx--allow-suspicious-udfs
sql
item_create.cc
Create_func_arg0Create_func_arg2Create_func_uuidCreate_func_pow
Create_native_func
item_create.cc
静态native_func_registry func_array [ ]
"LCASE"Create_func_lcase
item_func.hItem_str_func
item_func.cc
双_ Item函数的名称:_ VAL()函数的_ _隆龙item的名称:_:val(int *)_ item字符串的名称:_函数str():string str)
Item_num_funcval()::str()
current_thd->lex->safe_to_cache_query=0;
void Item_func_newname::fix_length_and_dec()
max_lengthmaybe_null = 0NULLItem_func_mod::fix_length_and_dec
NULL::val_int()null_value
::str()
String *strsql_string.h
::str()NULL
mysys/thr_lock
--skip-new
my.cnf
OPTIMIZE TABLEEXPLAIN
-DWITH_DEBUG=1--debug
-DWITH_DEBUG=1CMAKE_C_FLAGSCMAKE_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.dmpcore-file
c:\symbols
dir /s /b windbg.exe
windbg.exemysqld.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
--gdbSIGINT^C
thread_cache_sizemax_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
DBIDBI_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 0x9a6auth_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
EXPLAINSELECT
mysqld restartedhost_namemysql
--myisam-recover-optionshostname.errWarning: Repairing table
MyISAMGot 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_optionsd:t:i:O,\mysqld.trace
d
t
i
o,/tmp/mysqld.trace
debug_optionsprogram_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_ADMINSUPER
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;--------- | @ @调试| --------- | | ---------