文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>MySQL 5.1参考手册 :: 16. 编写自定义存储引擎(3)

MySQL 5.1参考手册 :: 16. 编写自定义存储引擎(3)

时间:2008-05-11  来源:sdccf

16.14. API引用

16.14.1. bas_ext 16.14.2. close 16.14.3. create 16.14.4. delete_row 16.14.5. delete_table 16.14.6. external_lock 16.14.7. extra 16.14.8. info 16.14.9. open 16.14.10. rnd_init 16.14.11. rnd_next 16.14.12. store_lock 16.14.13. update_row 16.14.14. write_row

16.14.1. bas_ext

目的

定义存储引擎所使用的文件扩展。

概要

virtual const char ** bas_ext ( );  
  ;

描述

这是bas_ext方法。调用它,可为MySQL服务器提供存储引擎所使用的文件扩展列表。该列表将返回以Null终结的字符串数组。

通过提供扩展列表,在很多情况下,存储引擎能省略delete_table()函数,这是因为MySQL服务器将关闭所有对表的引用,并使用指定的扩展删除所有文件。

参数

该函数无参数。

返回值

  • 返回值是存储引擎扩展的以Null终结的字符串数组。下面给出了CSV引擎的示例:

    static const char *ha_tina_exts[] = { ".CSV", NullS }; 

用法

static const char *ha_tina_exts[] = { ".CSV", NullS }; const char **ha_tina::bas_ext() const { return ha_tina_exts; } 

默认实施

static const char *ha_example_exts[] = { NullS }; const char **ha_example::bas_ext() const { return ha_example_exts; } 

16.14.2. close

目的

关闭打开的表。

概要

virtual int close ( void);  
  void ;

描述

这是close方法。

关闭表。这是释放任何已分配资源的恰当时机。

从sql_base.cc、sql_select.cc和table.cc调用它。在sql_select.cc中,它仅用于关闭临时表,或在将临时表转换为myisam表的过程中关闭表。关于sql_base.cc,请查看close_data_tables()。

参数

  • void

返回值

无返回值。

用法

取自CSV引擎的示例:

int ha_example::close(void) { DBUG_ENTER("ha_example::close"); DBUG_RETURN(free_share(share)); } 

16.14.3. create

目的

创建新表。

概要

virtual int create ( name,  
  form,  
  info);  
const char *  name ;
TABLE *  form ;
HA_CREATE_INFO *  info ;

描述

这是create方法。

调用create()以创建表。变量名称为表的名称。调用create()时,不需要打开表。此外,由于已创建了.frm文件,不推荐调整create_info。

由ha_create_table()从handle.cc中调用。

参数

  • name

  • form

  • info

返回值

无返回值。

用法

CSV搜索引擎示例:

int ha_tina::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) { char name_buff[FN_REFLEN]; File create_file; DBUG_ENTER("ha_tina::create"); if ((create_file= my_create(fn_format(name_buff, name, "", ".CSV", MY_REPLACE_EXT|MY_UNPACK_FILENAME),0, O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) DBUG_RETURN(-1); my_close(create_file,MYF(0)); DBUG_RETURN(0); } 

16.14.4. delete_row

目的

删除行。

概要

virtual int delete_row ( buf);  
const byte *  buf ;

描述

这是delete_row方法。

Buf包含删除行的副本。调用了当前行后,服务器将立刻调用它(通过前一个rnd_next()或索引调用)。如果存在指向上一行的指针,或能够访问 主键,删除操作将更为容易。请记住,服务器不保证连续删除。可以使用ORDER BY子句。

在sql_acl.cc和sql_udf.cc中调用,以管理内部的表信息。在sql_delete.cc、sql_insert.cc和sql_select.cc中调用。在sql_select中,它用于删除副本,而在插入操作中,它用于REPLACE调用。

参数

  • buf

返回值

无返回值。

用法

 

默认实施

{ return HA_ERR_WRONG_COMMAND; } 

16.14.5. delete_table

目的

用来自bas_ext()的扩展删除所有文件。

概要

virtual int delete_table ( name);  
const char *  name ;

描述

这是delete_table方法。

用于删除表。调用delete_table()时,所有已打开的对该表的引用均将被关闭(并释放全局共享的引用)。变量名称为表名。此时,需要删除任何已创建的文件。

如果未实施它,将从handler.cc调用默认的delete_table(),并用bas_ext()返回的文件扩展删除所有文件。假定处理程序返回的扩展比文件实际使用的多。

由delete_table和ha_create_table()从handler.cc调用。如果为存储引擎指定了table_flag HA_DROP_BEFORE_CREATE,仅在创建过程中使用。

参数

  • name: 表的基本名称

返回值

·         如果成功地从base_ext删除了至少1个文件而且未出现除ENOENT之外的错误,返回0。

·         #: Error

用法

大多数存储引擎均会忽略该函数的实施。

16.14.6. external_lock

目的

为事务处理表锁定。

概要

virtual int external_lock ( thd,  
  lock_type);  
THD *  thd ;
int  lock_type ;

描述

这是external_lock方法。

在lock.cc中“用于mysql的锁定函数”一节,给出了关于该议题的额外注释,值的一读。

在表上创建锁定。如果实施了能处理事务的存储引擎,请查看ha_berkely.cc,以了解如何执行该操作的方法。否则,应考虑在此调用flock()。

由lock_external()和unlock_external()从lock.cc中调用。也能由copy_data_between_tables()从sql_table.cc中调用。

参数

  • thd

  • lock_type

返回值

无返回值。

默认实施

{ return 0; } 

16.14.7. extra

目的

将提示从服务器传递给存储引擎。

概要

virtual int extra ( operation);  
enum ha_extra_function  operation ;

描述

这是extra方法。

无论何时,当服务器希望将提示发送到存储引擎时,将调用extra()。MyISAM引擎实现了大多数提示。ha_innodb.cc给出了最详尽的提示列表。

参数

  • operation

返回值

无返回值。

用法

 

默认实施

默认情况下,存储引擎倾向于不实施任何提示。

{ return 0; } 

16.14.8. info

目的

提示存储引擎通报统计信息。

概要

virtual void info ( uint);  
  uint ;

描述

这是info方法。

::info()用于将信息返回给优化程序。目前,该表处理程序未实施实际需要的大多数字段。SHOW也能利用该数据。注意,或许你打算在你的代码中包含下述内容“if (records > 2) records = 2”。原因在于,服务器仅优化具有一条记录的情形。如果在表扫描过程中,你不清楚记录的数目,最好将记录数设为2,以便能够返回尽可能多的所需记录。除了记录外,你或许还希望设置其他变量,包括:删除的记录,data_file_length,index_file_length,delete_length,check_time。更多信息,请参见handler.h中的公共变量。

在下述文件中调用:filesort.cc ha_heap.cc item_sum.cc opt_sum.cc sql_delete.cc sql_delete.cc sql_derived.cc sql_select.cc sql_select.cc sql_select.cc sql_select.cc sql_select.cc sql_show.cc sql_show.cc sql_show.cc sql_show.cc sql_table.cc sql_union.cc sql_update.cc

参数

  • uint

返回值

无返回值。

用法

该示例取自CSV存储引擎:

void ha_tina::info(uint flag) { DBUG_ENTER("ha_tina::info"); /* This is a lie, but you don't want the optimizer to see zero or 1 */ if (records < 2) records= 2; DBUG_VOID_RETURN; } 

16.14.9. open

目的

打开表。

概要

virtual int open ( name,  
  mode,  
  test_if_locked);  
const char *  name ;
int  mode ;
uint  test_if_locked ;

描述

这是open方法。

用于打开表。名称是文件的名称。在需要打开表时打开它。例如,当请求在表上执行选择操作时(对于每一请求,表未打开并被关闭,对其进行高速缓冲处理)。

由handler::ha_open()从handler.cc中调用。通过调用ha_open(),然后调用处理程序相关的open(),服务器打开所有表。

对于处理程序对象,将作为初始化的一部分并在将其用于正常查询之前打开它(并非总在元数据变化之前)。如果打开了对象,在删除之前还将关闭它。

这是open方法。调用open以打开数据库表。

第1个参数是要打开的表的名称。第2个参数决定了要打开的文件或将要执行的操作。这类值定义于handler.h中,为了方便起见在此列出:

        #define HA_OPEN_KEYFILE                 1
        #define HA_OPEN_RNDFILE                 2
        #define HA_GET_INDEX              4
        #define HA_GET_INFO                 8     /* do a ha_info() after open */
        #define HA_READ_ONLY              16    /* File opened as readonly */
        #define HA_TRY_READ_ONLY        32    /* Try readonly if can't open with read and write */
        #define HA_WAIT_IF_LOCKED       64      /* Wait if locked on open */
        #define HA_ABORT_IF_LOCKED    128       /* skip if locked on open.*/
        #define HA_BLOCK_LOCK             256   /* unlock when reading some records */
        #define HA_OPEN_TEMPORARY       512
      

最后的选项规定了在打开表之前是否应检查表上的锁定。

典型情况下,存储引擎需要实现某种形式的共享访问控制,以防止多线程环境下的文件损坏。关于如何实现文件锁定的示例,请参见sql/examples/ha_tina.cc的get_share()和free_share()方法。

参数

  • name

  • mode

  • test_if_locked

返回值

无返回值。

用法

该示例取自CSV存储引擎:

 int ha_tina::open(const char *name, int mode, uint test_if_locked) { DBUG_ENTER("ha_tina::open"); if (!(share= get_share(name, table))) DBUG_RETURN(1); thr_lock_data_init(&share->lock,&lock,NULL); ref_length=sizeof(off_t); DBUG_RETURN(0); } 

16.14.10. rnd_init

目的

为表扫描功能初始化处理程序。

概要

virtual int rnd_init ( scan);  
bool  scan ;

描述

这是rnd_init方法。

当系统希望存储引擎执行表扫描时,将调用rnd_init()。

与index_init()不同,rnd_init()可以调用两次,两次调用之间不使用rnd_end()(仅当scan=1时才有意义)。随后,第2次调用应准备好新的表扫描。例如,如果rnd_init分配了光标,第2次调用应将光标定位于表的开始部分,不需要撤销分配并再次分配。

从下述文件调用:filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc, 和sql_update.cc。

参数

  • scan

返回值

无返回值。

用法

该示例取自CSV存储引擎:

int ha_tina::rnd_init(bool scan) { DBUG_ENTER("ha_tina::rnd_init"); current_position= next_position= 0; records= 0; chain_ptr= chain; DBUG_RETURN(0); } 

16.14.11. rnd_next

目的

从表中读取下一行,并将其返回服务器。

概要

virtual int rnd_next ( buf);  
byte *  buf ;

描述

这是rnd_next方法。

对于表扫描的每一行调用它。耗尽记录时,应返回HA_ERR_END_OF_FILE。用行信息填充buff。表的字段结构是以服务器能理解的方式将数据保存到buf中的键。

从下述文件调用:filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc, 和sql_update.cc。

参数

  • buf

返回值

无返回值。

用法

下述示例取自ARCHIVE存储引擎:

int ha_archive::rnd_next(byte *buf) { int rc; DBUG_ENTER("ha_archive::rnd_next"); if (share->crashed) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); if (!scan_rows) DBUG_RETURN(HA_ERR_END_OF_FILE); scan_rows--; statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); current_position= gztell(archive); rc= get_row(archive, buf); if (rc != HA_ERR_END_OF_FILE) records++; DBUG_RETURN(rc); } 

16.14.12. store_lock

目的

创建和释放表锁定。

概要

virtual THR_LOCK_DATA ** store_lock ( thd,  
  to,  
  lock_type);  
THD *  thd ;
THR_LOCK_DATA **  to ;
enum thr_lock_type  lock_type ;

描述

这是store_lock方法。

下面介绍了关于handler::store_lock()的概念:

该语句决定了在表上需要何种锁定。对于updates/deletes/inserts,我们得到WRITE锁定;对于SELECT...,我们得到读锁定。

将锁定添加到表锁定处理程序之前(请参见thr_lock.c),mysqld将用请求的锁定调用存储锁定。目前,存储锁定能将写锁定更改为读锁定(或某些其他锁定),忽略锁定(如果不打算使用MySQL表锁定),或为很多表添加锁定(就像使用MERGE处理程序时那样)。

例如,Berkeley DB能够将所有的WRITE锁定更改为TL_WRITE_ALLOW_WRITE(表明正在执行WRITES操作,但我们仍允许其他人执行操作)。

释放锁定时,也将调用store_lock()。在这种情况下,通常不需要作任何事。

在某些特殊情况下,MySQL可能会发送对TL_IGNORE的请求。这意味着我们正在请求与上次相同的锁定,这也应被忽略(当我们打开了表的某一部分时,如果其他人执行了表刷新操作,就会出现该情况,此时,mysqld将关闭并再次打开表,然后获取与上次相同的锁定)。我们打算在将来删除该特性。

由get_lock_data()从lock.cc中调用。

参数

  • thd

  • to

  • lock_type

返回值

无返回值。

用法

下述示例取自ARCHIVE存储引擎:

/* Below is an example of how to setup row level locking. */ THR_LOCK_DATA **ha_archive::store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type) { if (lock_type == TL_WRITE_DELAYED) delayed_insert= TRUE; else delayed_insert= FALSE; if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) { /* Here is where we get into the guts of a row level lock. If TL_UNLOCK is set If we are not doing a LOCK TABLE or DISCARD/IMPORT TABLESPACE, then allow multiple writers */ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) && !thd->in_lock_tables && !thd->tablespace_op) lock_type = TL_WRITE_ALLOW_WRITE; /* In queries of type INSERT INTO t1 SELECT ... FROM t2 ... MySQL would use the lock TL_READ_NO_INSERT on t2, and that would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts to t2. Convert the lock to a normal read lock to allow concurrent inserts to t2. */ if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) lock_type = TL_READ; lock.type=lock_type; } *to++= &lock; return to; } 

16.14.13. update_row

目的

更新已有行的内容。

概要

virtual int update_row ( old_data,  
  new_data);  
const byte *  old_data ;
byte *  new_data ;

描述

这是update_row方法。

old_data将保存前一行的记录,而new_data将保存最新的数据。

如果使用了ORDER BY子句,服务器能够根据排序执行更新操作。不保证连续排序。

目前,new_data不会拥有已更新的auto_increament记录,或已更新的时间戳字段。你可以通过下述方式(例如)完成该操作:if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); if (table->next_number_field && record == table->record[0]) update_auto_increment();

从sql_select.cc, sql_acl.cc, sql_update.cc和sql_insert.cc调用。

参数

  • old_data

  • new_data

返回值

无返回值。

用法

 

默认实施

 { return HA_ERR_WRONG_COMMAND; } 

16.14.14. write_row

目的

为表添加新行。

概要

virtual int write_row ( buf);  
byte *  buf ;

描述

这是write_row方法。

write_row()用于插入行。目前,如果出现大量加载,不会给出任何extra()提示。buf是数据的字节数组,大小为table->s->reclength。

可以使用字段信息从本地字节数组类型提取数据。例如:

for (Field **field=table->field ; *field ; field++) { ... }

BLOB必须特殊处理:

    
for (ptr= table->s->blob_field, end= ptr + table->s->blob_fields ; ptr != end ; ptr++) 
  { 
        char *data_ptr; 
        uint32 size= ((Field_blob*)table->field[*ptr])->get_length();
        ((Field_blob*)table->field[*ptr])->get_ptr(&data_ptr); 
        ... 
  }

关于以字符串形式提取所有数据的示例,请参见ha_tina.cc。在ha_berkeley.cc中,对于ha_berkeley自己的本地存储类型,给出了一个通过“包装功能”完整保存它的例子。

请参见update_row()关于auto_increments和时间戳的注释。该情形也适用于write_row()。

从item_sum.cc、item_sum.cc、sql_acl.cc、sql_insert.cc、sql_insert.cc、sql_select.cc、sql_table.cc、sql_udf.cc、以及sql_update.cc调用。

参数

  • 数据的buf字节数组

返回值

无返回值。

用法

 

默认实施

 { return HA_ERR_WRONG_COMMAND; } 

这是MySQL参考手册的翻译版本,关于MySQL参考手册,请访问dev.mysql.com。 原始参考手册为英文版,与英文版参考手册相比,本翻译版可能不是最新的。

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载