1. 程式人生 > >淺談MySQL load data local infile細節 -- 從原始碼層面

淺談MySQL load data local infile細節 -- 從原始碼層面

相信大夥對mysql的load data local infile並不陌生,今天來鞏固一下這裡面隱藏的一些細節,對於想自己動手開發一個mysql客戶端有哪些點需要注意的呢?

首先,瞭解一下流程:

3個點

1、Is '<path>/<filename>' exists?對於客戶端來說,在檔案傳送前是先檢查一下檔案是否存在;

2、filename前建議加上絕對路徑

3、空包,表示命令已執行完畢。

接下來,一起來學習下官方原始碼(版本5.5.36)是如何實現該流程?由於篇幅關係,只貼出關鍵部分,其他讀者自行查閱原始碼。

首先,看看客戶端的核心實現,原始碼在libmysql\libmysql.c的handle_local_infile函式:

my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
 {
   /* initialize local infile (open file, usually) */
   ((*options->local_infile_init)(&li_ptr, net_filename,
     options->local_infile_userdata));
 
   /* read blocks of data from local infile callback */
   while
((readcount = (*options->local_infile_read)(li_ptr, buf, packet_length)) > 0); /* Send empty packet to mark end of file */ (my_net_write(net, (const uchar*) "", 0)) }

接下來,看看服務端的核心實現,原始碼在sql\sql_load.cc的mysql_load函式:

int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
             List
<Item> &fields_vars, List<Item> &set_fields, List<Item> &set_values, enum enum_duplicates handle_duplicates, bool ignore, bool read_file_from_client) { net_request_file(&thd->net,ex->file_name); // 接收客戶端發過來的檔案內容 while (!read_info.next_line()) ; /* ok to client sent only after binlog write and engine commit */ my_ok(thd, info.copied + info.deleted, 0L, name); } bool net_request_file(NET* net, const char* fname) { DBUG_ENTER("net_request_file"); DBUG_RETURN(net_write_command(net, 251, (uchar*) fname, strlen(fname), (uchar*) "", 0)); // 251即上圖的0xfb }

以上就是今天要聊的小細節,希望對大家有用,祝玩得開心!