5 08年5月

mysql load data infile

关键字:,

如何提高mysql load data infile的速度
测试数据2.5G,共有数据9427567条。用的mysql的large服务器的配置。
load一次需要大概10分钟左右。
建的表用的是MYISAM,调整了几个session的参数值

SET SESSION BULK_INSERT_BUFFER_SIZE=256217728;
SET SESSION MYISAM_SORT_BUFFER_SIZE=256217728;

运行结果如下

Query OK, 9427567 rows affected, 1558 warnings (3 min 55.21 sec)
Records: 9427567 Deleted: 0 Skipped: 0 Warnings: 0
google到的还可以

set global KEY_BUFFER_SIZE=256217728;
alter table tablename disable keys;

如何load数据里面带反斜杠(backslash)”\” 的数据
由于如果你没有指定FIELDS子句,则默认值为假设您写下如下语句时的值:
FIELDS TERMINATED BY ‘\t’ ENCLOSED BY ” ESCAPED BY ‘\\’
所以,如果你的数据里面有反斜杠(backslash)”\”的时候,数据会出现被截断的问题。出现这种问题,只要写上如下的fields子句即可
FIELDS TERMINATED BY ‘\t’ ENCLOSED BY ” ESCAPED BY ”

如何load不同编码的数据
原来用的4.X的mysql,我是select INTO OUTFILE ,只后用iconv,或者其他软件来做。可以参考这里,但是由于这次数据大,用ultraedit等软件打开都要半天。好在新版的mysql可以增加一个新的参数
CHARACTER SET gbk
我的文本数据是GBK的编码,数据表是utf8的,用这种方法测试成功。
如何load的时候只insert特定的列
比如表里面有比元数据多的列。可以在load的时候指定要插入的字段名字。

示例的代码如下:

LOAD DATA INFILE '~/data.txt'   
INTO TABLE fb0505   
CHARACTER SET  gbk   
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY ''
LINES TERMINATED BY '\n' STARTING BY '' 
(seller_id,fb_type,fb_date,item_url);

其中表fb0505里面还有一列是id。

贝贝爸 发表在 原创技术文章 | 等您写评论

22 07年7月

mysql去除特殊asc码

关键字:

要做一个mysql数据导入并且更新的工作。数据源是excel里来的。
选中excel里面左上角的元素,ctrl+shift+end,选中全部有内容的cell。另存为一个abc.txt的文件。
数据只有2列,建了一个有2列的表,准备把数据load进去,用root用户登录的,在mysql的shell运行如下命令
load data infile ‘/root/test.dat’ into table mytable FIELDS TERMINATED BY ‘\t’;
结果报错。
ERROR 13 (HY000): Can’t get stat of ‘/root/test.dat’ (Errcode: 13)
后来google,说是权限的问题,看来可能是mysql不能读root目录下的文件,随便换了个目录,问题解决。
load data infile ‘/tmp/test.dat’ into table ppname FIELDS TERMINATED BY ‘\t’;
但是后来出现的问题,基本让我崩溃。
举个例子

mysql> select * from mytable;
+------+------+
|
a    | b    |
+------+------+
 |
aaa  | aaa
+------+------+
1 row in set (0.00 sec)

肉眼看上去,a和b是一样的,然后我就按照一样的去匹配,奇怪的是怎么做都不行,刚开始以为是大小写的问题,作了lower操作还是不行。
后来开始不相信自己的眼睛了,查看一下到底是什么

mysql> select hex(a),hex(b) from mytable;
+--------+----------+
|
hex(a) | hex(b)   |
+--------+----------+
|
616161 | 6161610D |
+--------+----------+
1 row in set (0.00 sec)

这个时候才发现每个字符后边多了一个
0D
被这个问题搞了个把钟头,郁闷的要死。做了以下处理,终于乌云散尽看见阳光了。
update mytable set b=UNHEX(TRIM(TRAILING ‘0D’ FROM hex(b)));

奇怪的是我模拟不出来这种数据,本来以为是没有加“LINES TERMINATED BY ‘\n’”的问题,可是后来加了也不行,:S
看来眼见不一定为实啊。

贝贝爸 发表在 原创技术文章 | 等您写评论

7 07年6月

用mysqldumpslow分析mysql的slow query log

关键字:

mysql有一个功能就是可以log下来运行的比较慢的sql语句,默认是没有这个log的,为了开启这个功能,要修改my.cnf或者在mysql启动的时候加入一些参数。如果在my.cnf里面修改,需增加如下几行

long_query_time = 1
log-slow-queries = /var/youpath/slow.log
log-queries-not-using-indexes

long_query_time 是指执行超过多久的sql会被log下来,这里是1秒。
log-slow-queries 设置把日志写在那里,可以为空,系统会给一个缺省的文件host_name-slow.log,我生成的log就在mysql的data目录
log-queries-not-using-indexes 就是字面意思,log下来没有使用索引的query。

把上述参数打开,运行一段时间,就可以关掉了,省得影响生产环境。

接下来就是分析了,我这里的文件名字叫host-slow.log。
先mysqldumpslow –help以下,俺主要用的是
-s ORDER what to sort by (t, at, l, al, r, ar etc), ‘at’ is default
-t NUM just show the top n queries
-g PATTERN grep: only consider stmts that include this string

-s,是order的顺序,说明写的不够详细,俺用下来,包括看了代码,主要有
c,t,l,r和ac,at,al,ar,分别是按照query次数,时间,lock的时间和返回的记录数来排序,前面加了a的时倒叙
-t,是top n的意思,即为返回前面多少条的数据
-g,后边可以写一个正则匹配模式,大小写不敏感的

mysqldumpslow -s c -t 20 host-slow.log
mysqldumpslow -s r -t 20 host-slow.log

上述命令可以看出访问次数最多的20个sql语句和返回记录集最多的20个sql。
mysqldumpslow -t 10 -s t -g “left join” host-slow.log
这个是按照时间返回前10条里面含有左连接的sql语句。

用了这个工具就可以查询出来那些sql语句是性能的瓶颈,进行优化,比如加索引,该应用的实现方式等。

贝贝爸 发表在 原创技术文章 | 等您写评论

25 07年5月

apache child pid exit signal File size limit exceeded error

关键字:, ,

一个正常使用的网站,LAMP架构,突然打不开了,但是另外一个二级域名的网站,在同一台服务器上可以打开,静态文件也可以打开,因为出故障前有段时间程序没有更新,程序错误的可能性不大。
telnet 到网站的80端口,也可以打开,现象很奇怪。
重起了apache,没用,mysql用命令行也可以使用,没问题,一时没了方向。
于是tail了apache的log,一个是正常的web log,一个是error_log。
观察之后,发现了异常现象,apache的error_log一直输出错误信息如下:

[Thu May 24 23:11:27 2007] [notice] child pid 23406 exit signal File size limit exceeded (25)
[Thu May 24 23:12:01 2007] [notice] child pid 23544 exit signal File size limit exceeded (25)
[Thu May 24 23:12:47 2007] [notice] child pid 23633 exit signal File size limit exceeded (25)
[Thu May 24 23:12:53 2007] [notice] child pid 22799 exit signal File size limit exceeded (25)

说有文件大小超过了限制。
google了一下,说是超过了apache 2G的文件限制,试用find命令在系统里面查找超大的文件

find / -size +1000000k

查找到2个文件,一个是

/xxx/xxx/page_parse_time.log
/xxx/yyy/support-popbytes_log

第一个文件page_parse_time.log的大小在2G左右,压缩备份后,

> /xxx/xxx/page_parse_time.log

,问题解决。
page_parse_time.log的文件内容是程序记录sql query的log以及执行时间的log,每个页面请求都会写上一些数据,这么超过2G也不奇怪了。

上次还遇到过一次mysql数据条数过多,的问题
报错信息如下:

LOGSQL Insert Failed: insert into adodb_logsql (created,sql0,sql1,params,tracer,timer) values( NOW(),?,?,?,?,?) The table 'adodb_logsql' is full

经查

mysql> select count(*) from adodb_logsql ;
 +----------+
|
count(*) |
 +----------+
|
33127244 |
+----------+

3千万,,,可能是有点大了,最后truncate了这个表,问题解决
可是最后查mysql的文档,关于Scalability and Limits部分没有说mysql最多可以存多少条记录,估计跟表的类型也相关。原文说的是
Handles large databases. We use MySQL Server with databases that contain 50 million records. We also know of users who use MySQL Server with 60,000 tables and about 5,000,000,000 rows.
只是不知道它说的50 million是一个database里面的所有记录还是所有表的记录加起来。后边的应该是所有60,000个表加起来的数据量。
————————
结论,必要的日志是需要的,但是要控制大小,有循环机制,或者有监控机制,切记,切记。

贝贝爸 发表在 原创技术文章 | 等您写评论

13 07年3月

discuz mysql 数据库编码转换latin1->utf8

关键字:, ,

帮朋友的论坛做了一次编码转换的工作。系统是windows 2003,mysql4.1 discuz 5
本来以为很简单,dump数据
mysqldump -u root -p –opt –default-character-set=latin1 \
–skip-set-charset olddb cdb_members > d:\bak\cdb_members.sql
出来,用工具转一下编码,然后再导入
mysql -u root -p –default-character-set=utf8 newdb < d:\bak\cdb_members.sql

实际操作并没有想象的那么简单,最后解决的方案,也不是那么复杂。
阅读全部»

贝贝爸 发表在 原创技术文章 | 3个评论

10 07年3月

mysql tips

关键字:,

  • 运行在文本文件里的sql语句

shell> mysql db_name < text_file

还可以用一个USE db_name语句启动文本文件。在这种情况下,不需要在命令行中指定数据库名:

shell> mysql < text_file

如果正运行mysql,可以使用source或\.命令执行SQL脚本文件:

mysql> source filename

mysql> \. filename

贝贝爸 发表在 技术文章 | 等您写评论