在《mysql插入/更新数据》这篇文章提到,使用LOAD DATA INFILE语句,可以从一个文件直接加载数据到mysql中,但如果文件非常大,可能还需要对文件进行切割,分多次加载,这种情况下,可以使用pt-fifo-split工具将文件分割成多个数据块(chunks),从而控制每次传输到mysql服务器的数据量大小。
pt-fifo-split 可以模拟切割文件,并通过管道传递给先入先出队列而不用真正的切割文件。pt-fifo-split 是percona-toolkit 套件的一部分。
pt-fifo-split 命令用法:
pt-fifo-split [options] [FILE ...]
例如:使用pt-fifo-split分割一个大文件,每次读1000000行:
pt-fifo-split --lines hugefile.txt
while [ -e /tmp/pt-fifo-split ]; do cat /tmp/pt-fifo-split; done
pt-fifo-split 默认会在/tmp下面建立一个fifo文件,并读取大文件中的数据写入到fifo文件,每次达到指定行数就往fifo文件中打印一个EOF字符,读取完成以后,关闭掉fifo文件并移走,然后重建fifo文件,打印更多的行。这样可以保证你每次读取的时候都能读取到制定的行数直到读取完成。注意此工具只能工作在类unix操作系统。
常用选项:
--fifo /tmp/pt-fifo-split,指定fifo文件的路径;
--offset 0,如果不打算从第一行开始读,可以设置这个参数;
--lines 1000,每次读取的行数;
--force,如果fifo文件已经存在,就先删除它,然后重新创建一个fifo文件;
下面是一个完整的用法例子:
FLAT_FILE="/tmp/big_file.txt"
FIFO_PATH="${FLAT_FILE}.fifo"
LOAD_FILE="${FLAT_FILE}.load"
CHUNK_SIZE= # Split the file
pt-fifo-split --force --lines ${CHUNK_SIZE} ${FLAT_FILE} --fifo ${FIFO_PATH} &
# Sleep seconds to assure ${FIFO_PATH} exists before entering loop
sleep
while [ -e ${FIFO_PATH} ]
do
# Write chunk to disk
cat ${FIFO_PATH} > ${LOAD_FILE}
# Load chunk into table
mysql --database=test \
--show-warnings \
-vve "load data infile '${LOAD_FILE}' into table my_table;"
done
关于pt-fifo-split 性能评测可以参考这篇文章;