如何最小化mysqld写入磁盘的字节数?

时间:2013-12-28 18:46:13

标签: mysql linux raspberry-pi

我在raspberry pi(raspbian系统)上使用mysql服务器来存储传感器读数。每分钟将一条长度为20字节的记录插入到mysql表中。

但是iotop命令显示mysqld进程每分钟写入200K。我想尽量减少写入SD卡的大量数据,以扩展它的持久性(我已经应用了修复以防止SD卡损坏,比如日志和其他黑客的tmpfs)。

为什么当只有20B的数据插入表时mysqld写入200K字节?有没有办法在上面的场景中最小化写入,调整mysql服务器?

有趣的是vmstat命令没有在“io / bo”列中显示写入磁盘的数据

我使用mysql服务器版本5.5.33-0 + wheezy1和innoDB表。

更新

比尔在下面的详细解答让我意识到使用mysql服务器对于简单的传感器记录来说是一种过度杀伤。最终我迁移到了sqlite。对于相同的表结构,sqlite每个事务(大约30kb)写入的字节数比mysql少6倍,这对于RPi SD卡更好。我仍然在进行优化,因为正如我之前所说,每次交易我只写了20b的实际数据。

2 个答案:

答案 0 :(得分:5)

InnoDB将记录写入事务日志(ib_logfile *),这些日志是512字节对齐的。它还将信息写入第一个日志的标头。这是不可配置的,但您可以通过将innodb_flush_log_at_trx_commit变量更改为0来降低写入频率。

然后,无论您是否在该页面上只写了一个20字节的行,修改的页面都会以16KB的页面写入磁盘。在MySQL 5.6中,您可以使用innodb_page_size变量减小页面大小,最小为4KB。

页面也会在写入表空间中的相应位置之前写入双写缓冲区。您可以使用innodb_doublewrite变量禁用双写缓冲区。

页面也可以写入回滚段。这是不可配置的。

还有二进制日志。这与InnoDB无关,它用于任何存储引擎。如果你在Raspberry Pi上,我假设你不需要二进制日志。您可以使用log_bin变量禁用二进制日志(只是不要设置此变量,默认条件是它被禁用)。

您还可以禁用常规查询日志和慢速查询日志。

还有一个错误日志,但您无法禁用它。

答案 1 :(得分:4)

@BillKarwin非常好地回答了原因。在v5.5中你能做的最好的是16kb写入。如果你不能忍受这个,那么我将添加一些设计考虑因素。

不是编写每个传感器读数,而是在应用程序级别缓冲它们(例如tmpfs中的csv文件),并且在累积一定量之后使用LOAD DATA来读取它们。如果您必须有权访问它们(例如搜索),则可以更新应用程序查询以同时考虑“永久”MySQL存储和“临时”CSV存储。

当然,如果您能够在设备电源周期内容忍丢失,那么所有这些都是。