站内搜索: 请输入搜索关键词
当前页面: 在线文档首页 > MySQL 5.1参考手册中文版

Chapter聽16.聽Writing a Custom Storage Engine - MySQL 5.1参考手册中文版

绗16绔狅細缂栧啓鑷畾涔夊瓨鍌ㄥ紩鎿

16.1. 鍓嶈█

瀵逛簬MySQL 5.1MySQL AB鍏徃寮曞叆浜嗘彃浠跺紡瀛樺偍寮曟搸浣撶郴缁撴瀯锛岃繖鏍凤紝灏辫兘鍒涘缓鏂扮殑瀛樺偍寮曟搸锛屽苟灏嗗畠浠坊鍔犲埌姝e湪杩愯鐨MySQL鏈嶅姟鍣ㄤ笂锛岃屼笉蹇呴噸鏂扮紪璇戞湇鍔″櫒鏈韩銆

璇ヤ綋绯荤粨鏋勭畝鍖栦簡鏂板瓨鍌ㄥ紩鎿庣殑寮鍙戝拰閮ㄧ讲銆

鏈珷鐨勬剰鍥炬槸浣滀负鎸囧崡锛岀敤浜庡府鍔╀綘涓烘柊鐨勬彃浠跺紡瀛樺偍寮曟搸浣撶郴缁撴瀯寮鍙戝瓨鍌ㄥ紩鎿庛

鍏充簬MySQL鎻掍欢寮忓瓨鍌ㄥ紩鎿庝綋绯荤粨鏋勭殑鏇村淇℃伅锛岃鍙傝绗14绔狅細鎻掍欢寮忓瓨鍌ㄥ紩鎿庝綋绯荤粨鏋

16.2. 姒傝堪

MySQL鏈嶅姟鍣ㄩ噰鐢ㄤ簡妯″潡鍖栭鏍笺

鍥16.1锛歁ySQL浣撶郴缁撴瀯

MySQL architecture
瀛樺偍寮曟搸璐熻矗绠$悊鏁版嵁瀛樺偍锛屼互鍙MySQL鐨勭储寮曠鐞嗐傞氳繃瀹氫箟鐨APIMySQL鏈嶅姟鍣ㄨ兘澶熶笌瀛樺偍寮曟搸杩涜閫氫俊銆

姣忎釜瀛樺偍寮曟搸鍧囨槸1涓户鎵跨被锛屾瘡涓被瀹炰緥浣滀负澶勭悊绋嬪簭鑰岃寮曠敤銆

閽堝闇瑕佷笌鐗规畩琛ㄤ竴璧峰伐浣滅殑姣忎釜绾跨▼锛屽鐞嗙▼搴忔槸鍦1涓鐞嗙▼搴忕殑鍩虹涓婂疄渚嬪寲鐨勩備緥濡傦紝濡傛灉3涓繛鎺ュ叏閮藉湪鐩稿悓鐨勮〃涓婂伐浣滐紝闇瑕佸垱寤3涓鐞嗙▼搴忓疄渚嬨

涓鏃﹀垱寤轰簡澶勭悊绋嬪簭瀹炰緥锛MySQL鏈嶅姟鍣ㄥ皢鍚戝鐞嗙▼搴忓彂閫佸懡浠わ紝浠ヤ究鎵ц鏁版嵁瀛樺偍鍜屾绱换鍔★紝濡傛墦寮琛ㄣ佹搷绾佃鍜岀鐞嗙储寮曠瓑銆

鑳藉浠ョ疮杩涙柟寮忓垱寤哄畾鍒跺瓨鍌ㄥ紩鎿庯細寮鍙戜汉鍛樿兘澶熶互鍙瀛樺偍寮曟搸鍚姩锛岄殢鍚庢坊鍔犲INSERTUPDATEDELETE鎿嶄綔鐨勬敮鎸侊紝鐢氳嚦鑳藉澧炲姞瀵圭储寮曞姛鑳姐佷簨鍔″拰鍏朵粬楂樼骇鎿嶄綔鐨勬敮鎸併

16.3. 鍒涘缓瀛樺偍寮曟搸婧愭枃浠

瀹炴柦鏂板瓨鍌ㄥ紩鎿庣殑鏈绠鍗曟柟娉曟槸锛岄氳繃鎷疯礉鍜屾洿鏀EXAMPLE瀛樺偍寮曟搸寮濮嬨傚湪MySQL 5.1婧愮爜鏍戠殑sql/examples/鐩綍涓嬪彲鎵惧埌鏂囦欢ha_example.ccha_example.h銆傚叧浜庡浣曡幏寰5.1婧愮爜鏍戠殑璇存槑锛岃鍙傝2.8.3鑺傦紝鈥滀粠寮鍙戞簮鐮佹爲瀹夎鈥

澶嶅埗鏂囦欢鏃讹紝灏嗗悕绉颁粠ha_example.ccha_example.h鏇存敼涓轰笌瀛樺偍寮曟搸鐩搁傚簲鐨勫悕绉帮紝濡ha_foo.ccha_foo.h

鎷疯礉骞堕噸鍛藉悕浜嗚繖浜涙枃浠跺悗锛屽繀椤绘洿鎹㈡墍鏈夌殑EXAMPLE绀轰緥锛屼互鍙婂叿鏈夊瓨鍌ㄥ紩鎿庡悕绉扮殑绀轰緥銆傚鏋滀綘鐔熸倝sed锛屼篃鑳借嚜鍔ㄥ畬鎴愯繖浜涙楠わ細

sed s/EXAMPLE/FOO/g ha_example.h | sed s/example/foo/g ha_foo.h
sed s/EXAMPLE/FOO/g ha_example.cc | sed s/example/foo/g ha_foo.cc

16.4. 鍒涘缓handlerton

handlerton锛堚滃崟涓鐞嗙▼搴忊濈殑绠绉瀹氫箟浜嗗瓨鍌ㄥ紩鎿庯紝骞跺寘鍚寚鍚戝嚱鏁扮殑鍑芥暟鎸囬拡锛屽畠浠ユ暣浣撴柟寮忎綔鐢ㄥ湪寮曟搸涓婏紝鑰屽嚱鏁板伐浣滃湪鍗曠嫭鐨勫鐞嗙▼搴忓疄渚嬩腑銆傚湪杩欑被鍑芥暟鐨勪竴浜涚ず渚嬩腑锛屽寘鍚敤浜庡鐞嗘敞閲婂拰鍥炴粴鐨勪簨鍔″嚱鏁般

涓嬮潰缁欏嚭浜嗕竴涓潵鑷EXAMPLE瀛樺偍寮曟搸鐨勭ず渚嬶細

handlerton example_hton= {
  "EXAMPLE",
  SHOW_OPTION_YES,
  "Example storage engine", 
  DB_TYPE_EXAMPLE_DB,
  NULL,    /* Initialize */
  0,       /* slot */
  0,       /* savepoint size. */
  NULL,    /* close_connection */
  NULL,    /* savepoint */
  NULL,    /* rollback to savepoint */
  NULL,    /* release savepoint */
  NULL,    /* commit */
  NULL,    /* rollback */
  NULL,    /* prepare */
  NULL,    /* recover */
  NULL,    /* commit_by_xid */
  NULL,    /* rollback_by_xid */
  NULL,    /* create_cursor_read_view */
  NULL,    /* set_cursor_read_view */
  NULL,    /* close_cursor_read_view */
  example_create_handler,    /* Create a new handler */
  NULL,    /* Drop a database */
  NULL,    /* Panic call */
  NULL,    /* Release temporary latches */
  NULL,    /* Update Statistics */
  NULL,    /* Start Consistent Snapshot */
  NULL,    /* Flush logs */
  NULL,    /* Show status */
  NULL,    /* Replication Report Sent Binlog */
  HTON_CAN_RECREATE
};

涓嬮潰缁欏嚭浜嗘潵鑷handler.hhandlerton瀹氫箟锛

typedef struct
  {
    const char *name;
    SHOW_COMP_OPTION state;
    const char *comment;
    enum db_type db_type;
    bool (*init)();
    uint slot;
    uint savepoint_offset;
    int  (*close_connection)(THD *thd);
    int  (*savepoint_set)(THD *thd, void *sv);
    int  (*savepoint_rollback)(THD *thd, void *sv);
    int  (*savepoint_release)(THD *thd, void *sv);
    int  (*commit)(THD *thd, bool all);
    int  (*rollback)(THD *thd, bool all);
    int  (*prepare)(THD *thd, bool all);
    int  (*recover)(XID *xid_list, uint len);
    int  (*commit_by_xid)(XID *xid);
    int  (*rollback_by_xid)(XID *xid);
    void *(*create_cursor_read_view)();
    void (*set_cursor_read_view)(void *);
    void (*close_cursor_read_view)(void *);
    handler *(*create)(TABLE *table);
    void (*drop_database)(char* path);
    int (*panic)(enum ha_panic_function flag);
    int (*release_temporary_latches)(THD *thd);
    int (*update_statistics)();
    int (*start_consistent_snapshot)(THD *thd);
    bool (*flush_logs)();
    bool (*show_status)(THD *thd, stat_print_fn *print, enum ha_stat_type stat);
    int (*repl_report_sent_binlog)(THD *thd, char *log_file_name, my_off_t end_offset);
    uint32 flags;                                
  } handlerton;  

鍏辨湁30handlerton鍏冪礌锛屼絾鍙湁灏戦噺鍏冪礌鏄己鍒舵х殑锛堟槑纭湴璁叉槸鍓4涓厓绱犲拰绗21涓厓绱狅級銆

1.    瀛樺偍寮曟搸鐨勫悕绉般傝繖鏄垱寤鸿〃鏃跺皢浣跨敤鐨勫悕绉帮紙CREATE TABLE ... ENGINE = FOO;锛夈

2.    纭畾浣跨敤SHOW STORAGE ENGINES鍛戒护鏃舵槸鍚﹀垪鍑哄瓨鍌ㄥ紩鎿庛

3.    瀛樺偍寮曟搸娉ㄩ噴锛屽浣跨敤SHOW STORAGE ENGINES鍛戒护鏃舵樉绀虹殑瀛樺偍寮曟搸鐨勬弿杩般

4.    MySQL鏈嶅姟鍣ㄥ唴鍞竴璇嗗埆瀛樺偍寮曟搸鐨勬暣鏁般傚唴缃瓨鍌ㄥ紩鎿庝娇鐢ㄧ殑甯告暟瀹氫箟鍦handler.h鏂囦欢涓備綔涓哄垱寤哄父鏁扮殑鍙夋柟娉曪紝鍙娇鐢ㄥぇ浜25鐨勬暣鏁般

5.    鎸囧悜瀛樺偍寮曟搸鍒濆鍖栫▼搴忕殑鎸囬拡銆備粎褰撳惎鍔ㄦ湇鍔″櫒鏃舵墠璋冪敤璇ュ嚱鏁帮紝浠ヤ究鍦ㄥ疄渚嬪寲澶勭悊绋嬪簭涔嬪墠锛屽瓨鍌ㄥ紩鎿庣被鑳芥墽琛屽繀瑕佺殑鍐呭姟鎿嶄綔銆

6.    鎻掓Ы銆備繚瀛樻瘡杩炴帴鐨勪俊鎭椂锛屾瘡涓瓨鍌ㄥ紩鎿庡湪thd涓湁鑷繁鐨勫唴瀛樺尯鍩燂紙瀹為檯涓婁负鎸囬拡锛夈傚畠鏄綔涓thd->ha_data[foo_hton.slot]璁块棶鐨勩鎻掓Ы缂栧彿鍦ㄨ皟鐢foo_init()MySQL鍒濆鍖栥

7.    淇濆瓨鐐瑰亸绉汇備负浜嗕繚瀛樻瘡涓savepoint鏁版嵁锛屼负瀛樺偍寮曟搸鎻愪緵浜嗚姹傜殑澶у皬锛堝吀鍨嬫儏鍐典笅涓0锛夈

蹇呴』浠ラ潤鎬佹柟寮忓垵濮嬪寲savepoint鍋忕Щ锛屼娇鍏跺叿鏈夋墍鏈夌殑鍐呭瓨澶у皬锛屼互渚夸繚瀛樻瘡涓savepoint鐨勪俊鎭傚湪foo_init涔嬪悗锛屽畠琚洿鏀逛负savepoint瀛樺偍鍖哄煙鐨勫亸绉伙紝瀛樺偍寮曟搸涓嶉渶瑕佷娇鐢ㄥ畠銆

8.    鐢变簨鍔℃у瓨鍌ㄥ紩鎿庝娇鐢紝娓呯悊鍏跺瓨鍌ㄦ鍐呭垎閰嶇殑鍐呭瓨锛屽拰锛忔垨鍥炴粴浠讳綍鏈畬鎴愮殑浜嬪姟銆

9.    鐢变簨鍔℃у瓨鍌ㄥ紩鎿庨夋嫨鎬т娇鐢紝鍒涘缓savepoint锛堜繚瀛樼偣锛夛紝骞跺皢鍏朵繚瀛樺埌鎻愪緵鐨勫唴瀛樹腑銆

10.鎸囧悜澶勭悊绋嬪簭rollback_to_savepoint()鍑芥暟鐨勫嚱鏁版寚閽堛傚畠鐢ㄤ簬鍦ㄤ簨鍔℃湡闂磋繑鍥savepoint銆備粎瀵规敮鎸佷繚瀛樼偣鐨勫瓨鍌ㄥ紩鎿庢墠浼氬~鍏呭畠銆

11.鎸囧悜澶勭悊绋嬪簭release_savepoint()鍑芥暟鐨勫嚱鏁版寚閽堛傚畠鐢ㄤ簬鍦ㄤ簨鍔℃湡闂閲婃斁淇濆瓨鐐圭殑璧勬簮銆備粎瀵规敮鎸佷繚瀛樼偣鐨勫瓨鍌ㄥ紩鎿庢墠浼氬~鍏呭畠銆

12.鎸囧悜澶勭悊绋嬪簭commit()鍑芥暟鐨勫嚱鏁版寚閽堛瀹冪敤浜庢彁浜や簨鍔°備粎瀵规敮鎸佷簨鍔$殑瀛樺偍寮曟搸鎵嶄細濉厖瀹冦

13.鎸囧悜澶勭悊绋嬪簭rollback()鍑芥暟鐨勫嚱鏁版寚閽堛瀹冪敤浜庡洖婊氫氦鏄撱備粎瀵规敮鎸佷簨鍔$殑瀛樺偍寮曟搸鎵嶄細濉厖瀹冦

14.XA浜嬪姟鎬у瓨鍌ㄥ紩鎿庢墍闇銆備负鎻愪氦鎿嶄綔鍑嗗浜嬪姟銆傚皢XID涓庝簨鍔″叧鑱旇捣鏉ャ

15.XA浜嬪姟鎬у瓨鍌ㄥ紩鎿庢墍闇銆傛仮澶嶇敱XID鏍囪瘑鐨勪簨鍔°

16.XA浜嬪姟鎬у瓨鍌ㄥ紩鎿庢墍闇銆傛彁浜ょ敱XID鏍囪瘑鐨勪簨鍔°

17.XA浜嬪姟鎬у瓨鍌ㄥ紩鎿庢墍闇銆傚洖婊氱敱XID鏍囪瘑鐨勪簨鍔°

18.涓庢湇鍔″櫒绔厜鏍囦竴璧蜂娇鐢紝灏氭湭瀹炴柦銆

19.涓庢湇鍔″櫒绔厜鏍囦竴璧蜂娇鐢紝灏氭湭瀹炴柦銆

20.涓庢湇鍔″櫒绔厜鏍囦竴璧蜂娇鐢紝灏氭湭瀹炴柦銆

21.MANDATORY锛氭瀯閫犲苟杩斿洖澶勭悊绋嬪簭瀹炰緥銆

22.鎾ら攢鏂规鏃讹紝濡傛灉瀛樺偍寮曟搸闇瑕佹墽琛岀壒娈婃楠ゆ椂浣跨敤锛堝鍦ㄤ娇鐢ㄨ〃绌洪棿鐨勫瓨鍌ㄥ紩鎿庝腑浣跨敤锛夈

23.娓呯悊鍦ㄦ湇鍔″櫒鍏抽棴鍜屽穿婧冩椂璋冪敤鐨勫嚱鏁般

24.InnoDB鐗规畩鍑芥暟銆

25.鍦ㄥ惎鍔SHOW STATUS鏃惰皟鐢InnoDB鐗规畩鍑芥暟

26.璋冪敤InnoDB鐗规畩鍑芥暟浠ュ紑濮嬭繛缁鍙栥

27.璋冪敤瀹冿紝鎸囨槑搴斿皢鏃ュ織鍒锋柊涓哄彲闈犵殑瀛樺偍銆

28.鍦ㄥ瓨鍌ㄥ紩鎿庝笂鎻愪緵鍙浜哄憳璇诲彇鐨勭姸鎬佷俊鎭

29.InnoDB鐗规畩鍑芥暟鐢ㄤ簬澶嶅埗銆

30.Handlerton鏍囧織锛岄氬父涓ALTER TABLE鐩稿叧銆傚彲鑳界殑鍊煎畾涔変簬sql/handler.h鏂囦欢涓紝骞跺湪姝ゅ垪鍑猴紱

31.       #define HTON_NO_FLAGS                 0
32.       #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
33.       #define HTON_ALTER_NOT_SUPPORTED     (1 << 1)
34.       #define HTON_CAN_RECREATE            (1 << 2)
35.       #define HTON_FLUSH_AFTER_RENAME      (1 << 3)
36.       #define HTON_NOT_USER_SELECTABLE     (1 << 4)

HTON_ALTER_NOT_SUPPORTEDFEDERATED瀛樺偍寮曟搸浣跨敤锛岀敤浠ユ寚鏄庡瓨鍌ㄥ紩鎿庝笉鎺ュ彈AFTER TABLE璇彞銆

HTON_FLUSH_AFTER_RENAME鎸囨槑锛岄噸鍛藉悕琛ㄥ悗 锛屽繀椤昏皟鐢FLUSH LOGS

HTON_NOT_USER_SELECTABLE鎸囨槑瀛樺偍寮曟搸涓嶈兘鐢辩敤鎴烽夋嫨锛岃屾槸鐢ㄤ綔绯荤粺瀛樺偍寮曟搸锛屽鐢ㄤ簬浜岃繘鍒舵棩蹇楃殑浼瓨鍌ㄥ紩鎿庛

16.5. 瀵瑰鐞嗙▼搴忚繘琛屽疄渚嬪寲澶勭悊

璋冪敤瀛樺偍寮曟搸鐨勭1涓柟娉曟槸璋冪敤鏂扮殑澶勭悊绋嬪簭瀹炰緥銆

鍦ㄥ瓨鍌ㄥ紩鎿庢簮鏂囦欢涓畾涔handlerton涔嬪墠锛屽繀椤诲畾涔夌敤浜庡嚱鏁板疄渚嬪寲鐨勫嚱鏁伴澶淬涓嬮潰缁欏嚭浜1涓潵鑷CSV寮曟搸鐨勭ず渚嬶細

static handler* tina_create_handler(TABLE *table);

姝e浣犳墍瑙佸埌鐨勯偅鏍凤紝鍑芥暟鎺ュ彈鎸囧悜澶勭悊绋嬪簭鍑嗗绠$悊鐨勮〃鐨勬寚閽堬紝骞惰繑鍥炲鐞嗙▼搴忓璞°

瀹氫箟浜嗗嚱鏁伴澶村悗锛岀敤绗21handlerton鍏冪礌涓殑鍑芥暟鎸囬拡鍛藉悕鍑芥暟锛鎸囨槑鍑芥暟璐熻矗鐢熸垚鏂扮殑澶勭悊绋嬪簭瀹炰緥銆

涓嬮潰缁欏嚭浜MyISAM瀛樺偍寮曟搸鐨勫疄渚嬪寲鍑芥暟绀轰緥锛

static handler *myisam_create_handler(TABLE *table)
  {
    return new ha_myisam(table);
  }

璇ヨ皟鐢ㄩ殢鍚庝笌瀛樺偍寮曟搸鐨勬瀯閫犵▼搴忎竴璧峰伐浣溿備笅闈㈢粰鍑轰簡鏉ヨ嚜FEDERATED瀛樺偍寮曟搸鐨1涓ず渚嬶細

ha_federated::ha_federated(TABLE *table_arg)
  :handler(&federated_hton, table_arg),
  mysql(0), stored_result(0), scan_flag(0),
  ref_length(sizeof(MYSQL_ROW_OFFSET)), current_position(0)
  {}

涓嬮潰缁欏嚭浜嗘潵鑷EXAMPLE瀛樺偍寮曟搸鐨勫彟涓涓ず渚嬶細

ha_example::ha_example(TABLE *table_arg)
  :handler(&example_hton, table_arg)
  {}  

FEDERATED绀轰緥涓殑闄勫姞鍏冪礌鏄澶勭悊绋嬪簭鐨勯澶栧垵濮嬪寲瑕佺礌銆傛墍瑕佹眰鐨勬渶浣庡疄鏂芥槸EXAMPLE绀轰緥涓樉绀虹殑handler()鍒濆鍖栥

16.6. 瀹氫箟琛ㄦ墿灞

灏辩粰瀹氱殑琛ㄣ佹暟鎹拰绱㈠紩锛岃姹傚瓨鍌ㄥ紩鎿庝负MySQL鏈嶅姟鍣ㄦ彁渚涘瓨鍌ㄥ紩鎿庢墍浣跨敤鐨勬墿灞曞垪琛ㄣ

鎵╁睍搴旈噰鐢ㄤ互Null缁堢粨鐨勫瓧绗︿覆鏁扮粍褰㈠紡銆備笅闈㈢粰鍑轰簡CSV寮曟搸浣跨敤鐨勬暟缁勶細

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

璋冪敤bas_ext()鍑芥暟鏃惰繑鍥炶鏁扮粍銆

const char **ha_tina::bas_ext() const
{
  return ha_tina_exts;
}

閫氳繃鎻愪緵鎵╁睍淇℃伅锛屼綘杩樿兘蹇界暐DROP TABLE鍔熻兘鐨勫疄鏂斤紝杩欐槸鍥犱负锛岄氳繃鍏抽棴琛ㄥ苟鐢ㄤ綘鎸囧畾鐨勬墿灞曞垹闄ゆ墍鏈夋枃浠讹紝MySQL鏈嶅姟鍣ㄨ兘瀹炵幇璇ュ姛鑳姐

16.7. 鍒涘缓琛

涓鏃﹀疄渚嬪寲浜嗗鐞嗙▼搴忥紝鎵闇鐨勭1涓搷浣滃緢鍙兘鏄垱寤鸿〃銆

浣犵殑瀛樺偍寮曟搸蹇呴』瀹炵幇create()铏氭嫙鍑芥暟锛

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

璇ュ嚱鏁板簲鍒涘缓鎵鏈夊繀椤荤殑鏂囦欢锛岀劧鍚庡叧闂〃銆MySQL鏈嶅姟鍣ㄥ皢璋冪敤闅忓悗闇鎵撳紑鐨勮〃銆

*name鍙傛暟鏄〃鐨勫悕绉般*form鍙傛暟鏄痵t_table缁撴瀯锛岃缁撴瀯瀹氫箟浜嗚〃骞朵笌MySQL鏈嶅姟鍣ㄥ凡鍒涘缓鐨tablename.frm鏂囦欢鐨勫唴瀹瑰尮閰嶃傚湪澶у鏁版儏鍐典笅锛瀛樺偍寮曟搸涓嶉渶瑕佹洿鏀tablename.frm鏂囦欢锛屼篃娌℃湁鏀寔璇ユ搷浣滅殑棰勭疆鍔熻兘銆

*info鍙傛暟鏄寘鍚CREATE TABLE璇彞鐢ㄤ簬鍒涘缓琛ㄦ墍闇淇℃伅鐨勭粨鏋勩傝缁撴瀯瀹氫箟浜handler.h鏂囦欢涓紝骞朵负浜嗕究浜庡弬鑰冨垪浜庝笅闈細

typedef struct st_ha_create_information
  {
    CHARSET_INFO *table_charset, *default_table_charset;
    LEX_STRING connect_string;
    const char *comment,*password;
    const char *data_file_name, *index_file_name;
    const char *alias;
    ulonglong max_rows,min_rows;
    ulonglong auto_increment_value;
    ulong table_options;
    ulong avg_row_length;
    ulong raid_chunksize;
    ulong used_fields;
    SQL_LIST merge_list;
    enum db_type db_type;
    enum row_type row_type;
    uint null_bits;                       /* NULL bits at start of record */
    uint options;                                               /* OR of HA_CREATE_ options */
    uint raid_type,raid_chunks;
    uint merge_insert_method;
    uint extra_size;                      /* length of extra data segment */
    bool table_existed;                                     /* 1 in create if table existed */
    bool frm_only;                        /* 1 if no ha_create_table() */
    bool varchar;                         /* 1 if table has a VARCHAR */
  } HA_CREATE_INFO;

鍩烘湰鐨勫瓨鍌ㄥ紩鎿庤兘蹇界暐*form*info鐨勫唴瀹癸紝杩欐槸鍥犱负锛岀湡姝f墍闇鐨勬槸鍒涘缓瀛樺偍寮曟搸鎵浣跨敤鐨勬暟鎹枃浠讹紝浠ュ強瀵规暟鎹枃浠剁殑鍙兘鍒濆鍖栨搷浣滐紙鍋囧畾瀛樺偍鏂囦欢鏄熀浜庢枃浠剁殑锛夈

涓嬮潰缁欏嚭浜嗘潵鑷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);
  }

鍦ㄥ墠闈㈢殑渚嬪瓙涓紝CSV寮曟搸鏈紩鐢*table_arg*create_info鍙傛暟锛岃屾槸绠鍗曞湴鍒涘缓浜嗘墍闇鐨勬暟鎹枃浠讹紝鍏抽棴瀹冧滑锛屽苟杩斿洖銆

my_createmy_close鍑芥暟鏄畾涔変簬src/include/my_sys.h鏂囦欢涓殑鍔╂墜鍑芥暟銆

16.8. 鎵撳紑琛

鍦ㄨ〃涓婃墽琛屼换浣曡鎴栧啓鎿嶄綔涔嬪墠锛MySQL鏈嶅姟鍣ㄥ皢璋冪敤open()鏂规硶鎵撳紑琛ㄦ暟鎹拰绱㈠紩鏂囦欢锛堝鏋滃瓨鍦ㄧ殑璇濓級銆

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

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.ccget_share()free_share()鏂规硶銆

16.9. 瀹炴柦鍩烘湰鐨勮〃鎵弿鍔熻兘

鏈鍩烘湰鐨勫瓨鍌ㄥ紩鎿庤兘瀹炵幇鍙琛ㄦ壂鎻忓姛鑳姐傝繖绫诲紩鎿庡彲鐢ㄤ簬鏀寔SQL鏃ュ織鏌ヨ銆佷互鍙婂湪MySQL涔嬪濉厖鐨勫叾浠栨暟鎹枃浠躲

鏈妭浠嬬粛鐨勬柟娉曞疄鏂芥彁渚涗簡鍒涘缓鏇撮珮绾у瓨鍌ㄥ紩鎿庣殑鍩虹銆

涓嬮潰缁欏嚭浜嗗湪CSV寮曟搸鐨9琛岃〃鎵弿杩囩▼涓繘琛岀殑鏂规硶璋冪敤锛

ha_tina::store_lock
ha_tina::external_lock
ha_tina::info
ha_tina::rnd_init
ha_tina::extra - ENUM HA_EXTRA_CACHE   Cache record in HA_rrnd()
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::extra - ENUM HA_EXTRA_NO_CACHE   End cacheing of records (def)
ha_tina::external_lock
ha_tina::extra - ENUM HA_EXTRA_RESET   Reset database to after open

16.9.1. 瀹炴柦store_lock()鍑芥暟

鍦ㄦ墽琛屼换浣曡鍙栨垨鍐欐搷浣滀箣鍓嶏紝璋冪敤store_lock()鍑芥暟銆

灏嗛攣瀹氭坊鍔犲埌琛ㄩ攣瀹氬鐞嗙▼搴忎箣鍓嶏紙璇峰弬瑙thr_lock.c锛夛紝mysqld灏嗙敤璇锋眰鐨勯攣璋冪敤瀛樺偍閿佸畾銆傜洰鍓嶏紝瀛樺偍閿佸畾鑳藉皢鍐欓攣瀹氭洿鏀逛负璇婚攣瀹氾紙鎴栧叾浠栭攣瀹氾級锛屽拷鐣ラ攣瀹氾紙濡傛灉涓嶆墦绠椾娇鐢MySQL閿佸畾鐨勮瘽锛夛紝鎴栦负寰堝琛ㄦ坊鍔犻攣瀹氾紙灏卞儚浣跨敤MERGE澶勭悊绋嬪簭鏃朵綔鐨勯偅鏍凤級銆

渚嬪锛Berkeley DB鑳藉皢鎵鏈夌殑WRITE閿佸畾鏇存敼涓TL_WRITE_ALLOW_WRITE锛堣〃绀烘垜浠鍦ㄦ墽琛WRITES锛屼絾鎴戜滑浠嶅厑璁稿叾浠栦汉鍛樿繘琛屾搷浣滐級銆

閲婃斁閿佸畾鏃讹紝涔熷皢璋冪敤store_lock()锛屽湪杩欑鎯呭喌涓嬶紝閫氬父涓嶉渶鍋氫换浣曚簨銆

鍦ㄦ煇浜涚壒娈婃儏鍐典笅锛MySQL鍙兘浼氬彂閫佸TL_IGNORE鐨勮姹傘傝繖鎰忓懗鐫鎴戜滑姝e湪璇锋眰涓庝笂娆$浉鍚岀殑閿佸畾锛岃繖涔熷簲琚拷鐣ワ紙褰撴垜浠墦寮浜嗚〃鐨勬煇涓閮ㄥ垎鏃讹紝濡傛灉鍏朵粬浜烘墽琛屼簡琛ㄥ埛鏂版搷浣滐紝灏变細鍑虹幇璇ユ儏鍐碉紝姝ゆ椂锛mysqld灏嗗叧闂苟鍐嶆鎵撳紑琛紝鐒跺悗鑾峰彇涓庝笂娆$浉鍚岀殑閿佸畾锛夈傛垜浠墦绠楀湪灏嗘潵鍒犻櫎璇ョ壒鎬с

鍙兘鐨勯攣瀹氱被鍨嬪畾涔変簬includes/thr_lock.h涓紝骞跺垪鍦ㄤ笅闈細

enum thr_lock_type
{
         TL_IGNORE=-1,
                    TL_UNLOCK,                             /* UNLOCK ANY LOCK */
                    TL_READ,                                 /* Read lock */
                    TL_READ_WITH_SHARED_LOCKS,  
         TL_READ_HIGH_PRIORITY,      /* High prior. than TL_WRITE. Allow concurrent insert */
         TL_READ_NO_INSERT,                /* READ, Don't allow concurrent insert */
         TL_WRITE_ALLOW_WRITE,                   /*   Write lock, but allow other threads to read / write. */
         TL_WRITE_ALLOW_READ,        /*       Write lock, but allow other threads to read / write. */
         TL_WRITE_CONCURRENT_INSERT, /* WRITE lock used by concurrent insert. */
         TL_WRITE_DELAYED,                 /* Write used by INSERT DELAYED.  Allows READ locks */
         TL_WRITE_LOW_PRIORITY,            /* WRITE lock that has lower priority than TL_READ */
         TL_WRITE,                         /* Normal WRITE lock */
         TL_WRITE_ONLY               /* Abort new lock request with an error */
};  

瀹為檯鐨勯攣瀹氬鐞嗗洜閿佸畾瀹炴柦鐨勪笉鍚岃屼笉鍚岋紝浣犲彲浠ラ夋嫨鏌愪簺璇锋眰鐨勯攣瀹氱被鍨嬫垨涓嶉夋嫨浠讳綍閿佸畾绫诲瀷锛屽苟鏍规嵁鎯呭喌鎭板綋鍦颁唬鍏ヤ綘鑷繁鐨勬柟娉曘備笅闈㈢粰鍑轰簡1CSV瀛樺偍寮曟搸瀹炴柦绀轰緥锛

THR_LOCK_DATA **ha_tina::store_lock(THD *thd,
                                     THR_LOCK_DATA **to,
                                     enum thr_lock_type lock_type)
 {
   if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
     lock.type=lock_type;
   *to++= &lock;
   return to;

16.9.2. 瀹炴柦external_lock()鍑芥暟

external_lock()鍑芥暟鏄湪浜嬪姟寮濮嬫椂璋冪敤鐨勶紝鎴栧彂鍑LOCK TABLES璇彞鏃惰皟鐢ㄧ殑锛岀敤浜庝簨鍔℃у瓨鍌ㄥ紩鎿庛

sql/ha_innodb.ccsql/ha_berkeley.cc鏂囦欢涓紝鍙壘鍒浣跨敤external_lock()鐨勭ず渚嬶紝浣嗗ぇ澶氭暟瀛樺偍寮曟搸绠鍗曞湴杩斿洖0灏卞儚EXAMPLE瀛樺偍寮曟搸閭f牱锛

int ha_example::external_lock(THD *thd, int lock_type)
 {
   DBUG_ENTER("ha_example::external_lock");
   DBUG_RETURN(0);
 }

16.9.3. 瀹炴柦rnd_init()鍑芥暟

鍦ㄤ换浣曡〃鎵弿涔嬪墠璋冪敤鐨勫嚱鏁版槸rnd_init()鍑芥暟銆傚嚱鏁rnd_init()鐢ㄤ簬涓鸿〃鎵弿浣滃噯澶囷紝灏嗚鏁板櫒鍜屾寚閽堝浣嶄负琛ㄧ殑寮濮嬬姸鎬併

涓嬭堪绀轰緥鏉ヨ嚜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.9.4. 瀹炴柦info()鍑芥暟

鎵ц琛ㄦ壂鎻忔搷浣滀箣鍓嶏紝灏嗚皟鐢info()鍑芥暟锛屼互渚夸负浼樺寲绋嬪簭鎻愪緵棰濆淇℃伅銆

浼樺寲绋嬪簭鎵闇鐨勪俊鎭笉鏄氳繃杩斿洖鍊肩粰瀹氱殑锛屼綘闇濉厖瀛樺偍寮曟搸绫荤殑鐗瑰畾灞炴э紝褰info()璋冪敤杩斿洖鍚庯紝浼樺寲绋嬪簭灏嗚鍙栧瓨鍌ㄥ紩鎿庣被銆

闄や簡渚涗紭鍖栫▼搴忎娇鐢ㄥ锛屽湪璋冪敤info()鍑芥暟鏈熼棿锛屽緢澶氬奸泦鍚堣繕灏嗙敤浜SHOW TABLE STATUS璇彞銆

sql/handler.h涓垪鍑轰簡瀹屾暣鐨勫叕鍏卞睘鎬э紝涓嬮潰缁欏嚭浜嗕竴浜涘父瑙佺殑灞炴э細

ulonglong data_file_length;           /* Length off data file */
ulonglong max_data_file_length;       /* Length off data file */
ulonglong index_file_length;
ulonglong max_index_file_length;
ulonglong delete_length;              /* Free bytes */
ulonglong auto_increment_value;
ha_rows records;                      /* Records in table */
ha_rows deleted;                      /* Deleted records */
ulong raid_chunksize;
ulong mean_rec_length;         /* physical reclength */
time_t create_time;                   /* When table was created */
time_t check_time;
time_t update_time;  

瀵逛簬琛ㄦ壂鎻忥紝鏈閲嶈鐨勫睘鎬ф槸鈥records鈥锛屽畠鎸囨槑浜嗚〃涓殑璁板綍鏁般傚綋瀛樺偍寮曟搸鎸囨槑琛ㄤ腑鏈01琛屾椂锛屾垨鏈2琛屼互涓婃椂锛屽湪杩欎袱绉嶆儏鍐典笅锛屼紭鍖栫▼搴忕殑鎵ц鏂瑰紡涓嶅悓銆傚洜姝わ紝褰撲綘鍦ㄦ墽琛岃〃鎵弿涔嬪墠涓嶆竻妤氳〃涓湁澶氬皯琛屾椂锛屽簲杩斿洖澶т簬绛変簬2鐨勫硷紝杩欏緢閲嶈锛堜緥濡傦紝鏁版嵁鏄湪澶栭儴濉厖鐨勶級銆

16.9.5. 瀹炴柦extra()鍑芥暟

鎵ц鏌愪簺鎿嶄綔涔嬪墠锛屽簲璋冪敤extra()鍑芥暟锛屼互渚夸负瀛樺偍寮曟搸灏卞浣曟墽琛岀壒瀹氭搷浣滀簣浠ユ彁绀恒

棰濆璋冪敤涓殑鎻愮ず瀹炴柦涓嶆槸寮哄埗鎬х殑锛屽ぇ澶氭暟瀛樺偍寮曟搸鍧囪繑鍥0

int ha_tina::extra(enum ha_extra_function operation)
 {
   DBUG_ENTER("ha_tina::extra");
   DBUG_RETURN(0);
 }

16.9.6. 瀹炴柦rnd_next()鍑芥暟

瀹屾垚琛ㄧ殑鍒濆鍖栨搷浣滃悗锛MySQL鏈嶅姟鍣ㄥ皢璋冪敤澶勭悊绋嬪簭鐨rnd_next()鍑芥暟锛屾瘡涓や釜鎵弿琛岃皟鐢1娆★紝鐩磋嚦婊¤冻浜嗘湇鍔″櫒鐨勬悳绱㈡潯浠舵垨鍒拌揪鏂囦欢缁撳熬涓烘锛屽湪鍚庝竴绉嶆儏鍐典笅锛屽鐞嗙▼搴忓皢杩斿洖HA_ERR_END_OF_FILE

rnd_next()鍑芥暟鏈変竴涓悕涓*buf鐨勫崟瀛楄妭鏁扮粍鍙傛暟銆傚浜*buf鍙傛暟锛屽繀椤绘寜鍐呴儴MySQL鏍煎紡鐢ㄨ〃琛岀殑鍐呭濉厖瀹冦

鏈嶅姟鍣ㄩ噰鐢ㄤ簡涓夌鏁版嵁鏍煎紡锛氬浐瀹氶暱搴﹁锛屽彲鍙橀暱搴﹁锛屼互鍙婂叿鏈BLOB鎸囬拡鐨勫彲鍙橀暱搴﹁銆傚浜庢瘡绉嶆牸寮忥紝鍚勫垪灏嗘寜鐓у畠浠敱CREATE TABLE璇彞瀹氫箟鐨勯『搴忔樉绀猴紙琛ㄥ畾涔変繚瀛樺湪.frm鏂囦欢涓紝浼樺寲绋嬪簭鍜屽鐞嗙▼搴忓潎鑳戒粠鐩稿悓鐨勬簮锛屽嵆TABLE缁撴瀯锛岃闂〃鐨勫厓鏁版嵁锛夈

姣忕鏍煎紡浠ユ瘡鍒1姣旂壒鐨"NULL bitmap"寮濮嬨傚浜庡惈6涓垪鐨勮〃锛屽叾bitmap1瀛楄妭锛屽浜庡惈916鍒楃殑琛紝鍏bitmap2瀛楄妭锛屼緷姝ょ被鎺ㄣ傝鎯虫寚鏄庣壒瀹氱殑鍊兼槸NULL锛屽簲灏嗚鍒NULL浣嶈缃负1

NULL bitmap閫愪釜杩涘叆鍒楀悗锛屾瘡鍒楀皢鍏锋湁MySQL鎵嬪唽鐨勨MySQL鏁版嵁绫诲瀷鈥濅竴鑺備腑鎸囧畾鐨勫ぇ灏忋傚湪鏈嶅姟鍣ㄤ腑锛屽垪鐨勬暟鎹被鍨嬪畾涔夊湪sql/field.cc鏂囦欢涓傚浜庡浐瀹氶暱搴﹁鏍煎紡锛屽垪灏嗙畝鍗曞湴閫愪釜鏀剧疆銆傚浜庡彲鍙橀暱搴﹁锛VARCHAR鍒楀皢琚紪鐮佷负1瀛楄妭闀匡紝鍚庤窡瀛楃涓层傚浜庡叿鏈BLOB鍒楃殑鍙彉闀垮害琛岋紝姣忎釜blob鐢变袱閮ㄥ垎琛ㄧず锛氶鍏堟槸琛ㄧずBLOB瀹為檯澶у皬鐨勬暣鏁帮紝鐒跺悗鏄寚鍚戝唴瀛樹腑BLOB鐨勬寚閽堛

鍦ㄤ换浣曡〃澶勭悊绋嬪簭涓粠rnd_next()寮濮嬶紝鍙壘鍒琛岃浆鎹紙鎴栤滃寘瑁呪濓級鐨勭ず渚嬨備緥濡傦紝鍦ha_tina.cc涓紝find_current_row()鍐呯殑浠g爜缁欏嚭浜嗕娇鐢TABLE缁撴瀯锛堢敱琛ㄦ寚鍚戠殑锛夊拰瀛楃涓插璞★紙鍛藉悕缂撳啿锛夊寘瑁呭瓧绗︽暟鎹紙鏉ヨ嚜CSV鏂囦欢锛夌殑鏂规硶銆傚皢琛屽啓鍥炵鐩橀渶瑕佸弽鍚戣浆鎹紝浠庡唴閮ㄦ牸寮忚В鍖呫

涓嬭堪绀轰緥鏉ヨ嚜CSV瀛樺偍寮曟搸锛

int ha_tina::rnd_next(byte *buf)
 {
   DBUG_ENTER("ha_tina::rnd_next");
 
   statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status);
 
   current_position= next_position;
   if (!share->mapped_file)
     DBUG_RETURN(HA_ERR_END_OF_FILE);
   if (HA_ERR_END_OF_FILE == find_current_row(buf) )
     DBUG_RETURN(HA_ERR_END_OF_FILE);
 
   records++;
   DBUG_RETURN(0);

瀵逛簬浠庡唴閮ㄨ鏍煎紡鍒CSV琛屾牸寮忕殑杞崲锛屽畠鏄湪find_current_row()鍑芥暟涓墽琛岀殑銆

int ha_tina::find_current_row(byte *buf)
 {
   byte *mapped_ptr= (byte *)share->mapped_file + current_position;
   byte *end_ptr;
   DBUG_ENTER("ha_tina::find_current_row");
 
   /* EOF should be counted as new line */
   if ((end_ptr=  find_eoln(share->mapped_file, current_position,
                            share->file_stat.st_size)) == 0)
     DBUG_RETURN(HA_ERR_END_OF_FILE);
 
   for (Field **field=table->field ; *field ; field++)
   {
     buffer.length(0);
     mapped_ptr++; // Increment past the first quote
     for(;mapped_ptr != end_ptr; mapped_ptr++)
     {
       // Need to convert line feeds!
       if (*mapped_ptr == '"' &&
           (((mapped_ptr[1] == ',') && (mapped_ptr[2] == '"')) ||
            (mapped_ptr == end_ptr -1 )))
       {
         mapped_ptr += 2; // Move past the , and the "
         break;
       }
       if (*mapped_ptr == '\\' && mapped_ptr != (end_ptr - 1))
       {
         mapped_ptr++;
         if (*mapped_ptr == 'r')
           buffer.append('\r');
         else if (*mapped_ptr == 'n' )
           buffer.append('\n');
         else if ((*mapped_ptr == '\\') || (*mapped_ptr == '"'))
           buffer.append(*mapped_ptr);
         else  /* This could only happed with an externally created file */
         {
           buffer.append('\\');
           buffer.append(*mapped_ptr);
         }
       }
       else
         buffer.append(*mapped_ptr);
     }
     (*field)->store(buffer.ptr(), buffer.length(), system_charset_info);
   }
   next_position= (end_ptr - share->mapped_file)+1;
   /* Maybe use \N for null? */
   memset(buf, 0, table->s->null_bytes); /* We do not implement nulls! */
 
   DBUG_RETURN(0);

16.10. 鍏抽棴琛

MySQL鏈嶅姟鍣ㄥ畬鎴愯〃鎿嶄綔鏃讹紝瀹冨皢璋冪敤close()鏂规硶鍏抽棴鏂囦欢鎸囬拡骞堕噴鏀句换浣曞叾浠栬祫婧愩

瀵逛簬浣跨敤鍏变韩璁块棶鏂规硶鐨勫瓨鍌ㄥ紩鎿庯紙濡CSV寮曟搸鍜屽叾浠栫ず渚嬪紩鎿庝腑鏄剧ず鐨勬柟娉曪級锛屽繀椤诲皢瀹冧滑鑷繁浠庡叡浜粨鏋勪腑鍒犻櫎锛

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

瀵逛簬浣跨敤鍏惰嚜宸卞叡浜鐞嗙郴缁熺殑瀛樺偍寮曟搸锛屽簲浣跨敤浠讳綍鎵闇鐨勬柟娉曪紝鍦ㄥ畠浠殑澶勭悊绋嬪簭涓紝浠庡凡鎵撳紑琛ㄧ殑鍏变韩鍖哄垹闄ゅ鐞嗙▼搴忓疄渚嬨

16.11. 涓哄瓨鍌ㄥ紩鎿庢坊鍔犲INSERT鐨勬敮鎸

涓鏃﹀湪浣犵殑瀛樺偍寮曟搸涓湁浜嗚鏀寔锛屼笅涓涓渶瑕佸疄鏂界殑鐗规ф槸瀵INSERT璇彞鐨勬敮鎸併傛湁浜INSERT鏀寔锛屽瓨鍌ㄥ紩鎿庡氨鑳藉鐞WORM锛堝啓涓娆★紝璇诲娆★級搴旂敤绋嬪簭锛屽鐢ㄤ簬浠ュ悗鍒嗘瀽鐨勬棩蹇楀拰褰掓。搴旂敤绛夈

鎵鏈夌殑INSERT鎿嶄綔鍧囨槸閫氳繃write_row()鍑芥暟浜堜互澶勭悊鐨勶細

int ha_foo::write_row(byte *buf)  

*buf鍙傛暟鍖呭惈灏嗚鎻掑叆鐨勮锛岄噰鐢ㄥ唴閮MySQL鏍煎紡銆傚熀鏈殑瀛樺偍寮曟搸灏嗙畝鍗曞湴鍓嶈繘鍒版暟鎹枃浠舵湯灏撅紝骞剁洿鎺ュ湪鏈熬澶勬坊鍔犵紦鍐茬殑鍐呭锛岃繖鏍峰氨鑳戒娇琛岃鍙栧彉寰楃畝鍗曪紝杩欐槸鍥犱负锛屼綘鍙互璇诲彇琛屽苟灏嗗叾鐩存帴浼犻掑埌rnd_next()鍑芥暟鐨缂撳啿鍙傛暟涓

鍐欏叆琛岀殑杩涚▼涓庤鍙栬鐨勮繘绋嬬浉鍙嶏細浠MySQL鍐呴儴琛屾牸寮忚幏鍙栨暟鎹紝骞跺皢鍏跺啓鍏ユ暟鎹枃浠躲備笅杩扮ず渚嬫潵鑷CSV瀛樺偍寮曟搸锛

int ha_tina::write_row(byte * buf)
 {
   int size;
   DBUG_ENTER("ha_tina::write_row");
 
   statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
 
   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
     table->timestamp_field->set_time();
 
   size= encode_quote(buf);
 
   if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP)))
     DBUG_RETURN(-1);
 
   if (get_mmap(share, 0) > 0)
     DBUG_RETURN(-1);
   DBUG_RETURN(0);
 }

鍓嶈堪绀轰緥涓殑涓ゆ潯娉ㄩ噴鍖呮嫭锛屾洿鏂板叧浜庡啓鍏ユ搷浣滅殑琛ㄧ粺璁★紝浠ュ強鍦ㄥ啓鍏ヨ涔嬪墠璁剧疆鏃堕棿鎴炽

16.12. 涓哄瓨鍌ㄥ紩鎿庢坊鍔犲UPDATE鐨勬敮鎸

閫氳繃鎵ц琛ㄦ壂鎻忔搷浣滐紝鍦ㄦ壘鍒颁笌UPDATE璇彞鐨WHERE瀛愬彞鍖归厤鐨勮鍚庯紝MySQL鏈嶅姟鍣ㄥ皢鎵цUPDATE璇彞锛鐒跺悗璋冪敤update_row()鍑芥暟

int ha_foo::update_row(const byte *old_data, byte *new_data)

*old_data鍙傛暟鍖呭惈鏇存柊鍓嶄綅浜庤涓殑鏁版嵁锛*new_data鍙傛暟鍖呭惈琛岀殑鏂板唴瀹癸紙閲囩敤MySQL鍐呴儴琛屾牸寮忥級銆

鏇存柊鐨勬墽琛屽彇鍐充簬琛屾牸寮忓拰瀛樺偍瀹炴柦鏂瑰紡銆傛煇浜涘瓨鍌ㄥ紩鎿庡皢鏇挎崲鎭板綋浣嶇疆鐨勬暟鎹紝鑰屽叾浠栧疄鏂芥柟妗堝垯浼氬垹闄ゅ凡鏈夌殑琛岋紝骞跺湪鏁版嵁鏂囦欢鏈熬娣诲姞鏂拌銆

闈炰簨鍔℃у瓨鍌ㄥ紩鎿庨氬父浼氬拷鐣*old_data鍙傛暟鐨勫唴瀹癸紝浠呭鐞*new_data缂撳啿銆浜嬪姟鎬у瓨鍌ㄥ紩鎿庡彲鑳介渶瑕佹瘮杈冪紦鍐诧紝浠ョ‘瀹氬湪涓婃鍥炴粴涓嚭鐜颁簡浠涔堝彉鍖栥

濡傛灉姝e湪鏇存柊鐨勮〃涓寘鍚椂闂存埑鍒楋紝瀵规椂闂存埑鐨勬洿鏂板皢鐢update_row()璋冪敤绠$悊銆涓嬭堪绀轰緥鏉ヨ嚜CSV寮曟搸锛

int ha_tina::update_row(const byte * old_data, byte * new_data)
 {
   int size;
   DBUG_ENTER("ha_tina::update_row");
 
   statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
                     &LOCK_status);
 
   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
     table->timestamp_field->set_time();
 
   size= encode_quote(new_data);
 
   if (chain_append())
     DBUG_RETURN(-1);
 
   if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP)))
     DBUG_RETURN(-1);
   DBUG_RETURN(0);
 }

璇锋敞鎰忎笂渚嬩腑鐨勬椂闂存埑璁剧疆銆

16.13. 涓哄瓨鍌ㄥ紩鎿庢坊鍔犲DELETE鐨勬敮鎸

MySQL鏈嶅姟鍣ㄩ噰鐢ㄤ簡涓INSERT璇彞鐩稿悓鐨勬柟娉曟潵鎵цDELETE璇彞锛氭湇鍔″櫒浣跨敤rnd_next()鍑芥暟璺冲埌瑕佸垹闄ょ殑琛岋紝鐒跺悗璋冪敤delete_row()鍑芥暟鍒犻櫎琛屻

int ha_foo::delete_row(const byte *buf)

*buf鍙傛暟鍖呭惈瑕佸垹闄よ鐨勫唴瀹广傚浜庡ぇ澶氭暟瀛樺偍寮曟搸锛岃鍙傛暟鍙蹇界暐锛屼絾浜嬪姟鎬у瓨鍌ㄥ紩鎿庡彲鑳介渶瑕佷繚瀛樺垹闄ょ殑鏁版嵁锛屼互渚涘洖婊氭搷浣滀娇鐢ㄣ

涓嬭堪绀轰緥鏉ヨ嚜CSV瀛樺偍寮曟搸锛

int ha_tina::delete_row(const byte * buf)
 {
   DBUG_ENTER("ha_tina::delete_row");
   statistic_increment(table->in_use->status_var.ha_delete_count,
                       &LOCK_status);
 
   if (chain_append())
     DBUG_RETURN(-1);
  
   --records;
 
   DBUG_RETURN(0);
 }

鍓嶈堪绀轰緥鐨勬楠ゆ槸鏇存柊delete_count缁熻锛屽苟璁板綍璁℃暟銆

16.14. API寮曠敤

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.ccsql_select.cctable.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.ccsql_udf.cc涓皟鐢紝浠ョ鐞嗗唴閮ㄧ殑琛ㄤ俊鎭sql_delete.ccsql_insert.ccsql_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_tableha_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涔熻兘鍒╃敤璇ユ暟鎹傛敞鎰忥紝鎴栬浣犳墦绠楀湪浣犵殑浠g爜涓寘鍚笅杩板唴瀹光if (records > 2) records = 2鈥濄傚師鍥犲湪浜庯紝鏈嶅姟鍣ㄤ粎浼樺寲鍏锋湁涓鏉¤褰曠殑鎯呭舰銆傚鏋滃湪琛ㄦ壂鎻忚繃绋嬩腑锛屼綘涓嶆竻妤氳褰曠殑鏁扮洰锛屾渶濂藉皢璁板綍鏁拌涓2锛屼互渚胯兘澶熻繑鍥炲敖鍙兘澶氱殑鎵闇璁板綍銆傞櫎浜嗚褰曞锛屼綘鎴栬杩樺笇鏈涜缃叾浠栧彉閲忥紝鍖呮嫭锛氬垹闄ょ殑璁板綍锛data_file_lengthindex_file_lengthdelete_lengthcheck_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()锛屾湇鍔″櫒鎵撳紑鎵鏈夎〃銆

瀵逛簬澶勭悊绋嬪簭瀵硅薄锛屽皢浣滀负鍒濆鍖栫殑涓閮ㄥ垎骞跺湪灏嗗叾鐢ㄤ簬姝e父鏌ヨ涔嬪墠鎵撳紑瀹冿紙骞堕潪鎬诲湪鍏冩暟鎹彉鍖栦箣鍓嶏級銆傚鏋滄墦寮浜嗗璞★紝鍦ㄥ垹闄や箣鍓嶈繕灏嗗叧闂畠銆

杩欐槸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.ccget_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銆傝〃鐨勫瓧娈电粨鏋勬槸浠ユ湇鍔″櫒鑳界悊瑙g殑鏂瑰紡灏嗘暟鎹繚瀛樺埌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鐨勮姹傘傝繖鎰忓懗鐫鎴戜滑姝e湪璇锋眰涓庝笂娆$浉鍚岀殑閿佸畾锛岃繖涔熷簲琚拷鐣ワ紙褰撴垜浠墦寮浜嗚〃鐨勬煇涓閮ㄥ垎鏃讹紝濡傛灉鍏朵粬浜烘墽琛屼簡琛ㄥ埛鏂版搷浣滐紝灏变細鍑虹幇璇ユ儏鍐碉紝姝ゆ椂锛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.ccsql_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.ccitem_sum.ccsql_acl.ccsql_insert.ccsql_insert.ccsql_select.ccsql_table.ccsql_udf.cc銆佷互鍙sql_update.cc璋冪敤銆

鍙傛暟

  • 鏁版嵁鐨buf瀛楄妭鏁扮粍

杩斿洖鍊

鏃犺繑鍥炲笺

鐢ㄦ硶

          
        

榛樿瀹炴柦

           { return  HA_ERR_WRONG_COMMAND; }
        

杩欐槸MySQL鍙傝冩墜鍐岀殑缈昏瘧鐗堟湰锛屽叧浜嶮ySQL鍙傝冩墜鍐岋紝璇疯闂dev.mysql.com銆 鍘熷鍙傝冩墜鍐屼负鑻辨枃鐗堬紝涓庤嫳鏂囩増鍙傝冩墜鍐岀浉姣旓紝鏈炕璇戠増鍙兘涓嶆槸鏈鏂扮殑銆