Encodingチェックの強化
TritonnではSennaのインデックスを作る際、MySQLのテーブル定義情報(CREATE文、ALTER文)の情報を利用して適切な文字コードを自動的に選ぶように実装しています。この時、プログラム的にチェックが甘い部分があったのですが、またもやnkjm氏がサクッと修正してくれました!
------------------------------------------------------------------------ r73 | nkjm | 2007-06-27 15:22:14 +0900 (水, 27 6月 2007) | 13 lines myisam/ft_update.c Added code to check the value of senna_encoding myisam/ft_update.c Added code to check the value of senna_encoding myisam/mi_create.c Added code to check the value of senna_encoding
merge履歴
というわけでmerge。
Merged from mysql-5.0-community/trunk Added code to check the value of senna_encoding svn merge -r72:73 mysql-5.0-community/trunk mysql-5.0-enterprise/trunk
新プロダクト MySQL Proxy リリース
LOAD DATAコマンドを調べる
SQLパーサ部分
sql/sql_yacc.yyにて。SQLコマンドはSQLCOM_LOADらしい。
load_data: load_data_lock opt_local INFILE TEXT_STRING_filesystem { LEX *lex=Lex; lex->sql_command= SQLCOM_LOAD; lex->lock_option= $1; lex->local_file= $2; lex->duplicates= DUP_ERROR; lex->ignore= 0; if (!(lex->exchange= new sql_exchange($4.str, 0))) MYSQL_YYABORT; }
dispatch部分
sql/sql_parse.ccのmysql_execute_command関数のswitch-caseにて。mysql_load関数が処理する。
case SQLCOM_LOAD: { 〜中略〜 res= mysql_load(thd, lex->exchange, first_table, lex->field_list, lex->update_list, lex->value_list, lex->duplicates, lex->ignore, (bool) lex->local_file); break; }
mysql_load関数
sql/sql_load.ccのmysql_load関数より抜粋。
対象テーブルにロックをかける。
if (open_and_lock_tables(thd, table_list))
トランザクション対応テーブルかどうかを調べる。
transactional_table= table->file->has_transactions();
バルクインサート実行。
table->file->start_bulk_insert((ha_rows) 0);
おまけ
LOAD DATAを実行した後、mysqlbinlogで確認すると、インポートに使用したファイルと同じ内容のファイルが/tmp以下に生成されていてそこからLOAD DATAするように書かれている。
こんな感じ。
# at 316 #070627 10:16:12 server id 1 end_log_pos 450 Execute_load_query thread_id=1 exec_time=0 error_code=0 SET TIMESTAMP=1182906972/*!*/; load data LOCAL INFILE '/tmp/SQL_LOAD_MB-1-1' INTO table t1/*!*/; # file_id: 1
この/tmp/SQL_LOAD_MB-1-1なんてファイルはオイラは知らねという話。
実はこれは、mysqldがやっていることではなく、LOAD DATA処理により発生したbulk insert文をリストア時にさらに高速化するために、mysqlbinlogコマンドがやっていること。
client/mysqlbinlog.ccにて。
int Load_log_processor::process(Begin_load_query_log_event *blqe) { return process_first_event("SQL_LOAD_MB", 11, blqe->block, blqe->block_len, blqe->file_id, 0); }
Load_log_processor::process関数のDescription。
Creates temporary file to be used in LOAD DATA and writes first block of data to it. Registers its file name (and optional Create_file event) in the array of active temporary files.
従って、mysqldが稼働しているサーバで、大量データをLOAD DATAコマンドでインポートするときに/tmpを含むパーティションがいっぱいになってしまうとか心配する必要はなくて、敢えて留意するとしたら、mysqlbinlogを使ってリストアする(正確にいうとmysqlbinlogを実行してバイナリログをテキスト表示する)マシンのハードディスクに空きがあるかどうかという話だと思われる。