你好,在 EC2 服务器上,我使用以下命令从另一台服务器对 SQL 进行 gzip 压缩:
mysqldump -h $HOST -u $UNAME -p$PWORD --single-transaction $1 | gzip -5 > $2_`date +%d`.sql.gz
目前 SQL 数据为 560 Mb,以下是来自“免费”的信息:
total used free shared buffers cached
Mem: 2049568 1731356 318212 360 144328 529472
-/+ buffers/cache: 1057556 992012
Swap: 0 0 0
我想知道如果我有 1 Gb 或 2 Gb 的 SQL 数据,它会如何工作?它会在接收数据时执行 gzip 以最大限度地减少 RAM 使用量吗?还是先获取整个 SQL 数据,然后再对其进行 gzip?
答案1
除了远程系统上的转储之外,此命令占用的内存非常少。Mysqldump 可以根据需要将数据文件分页到内存中。索引不太可能被使用,因此不需要读取数据文件中的所有块。除了从磁盘读取块的额外 I/O 之外,可能还有额外的 I/O 来替换缓冲区中的块。由于这发生在另一个系统上,因此本地影响只是网络数据缓冲区的少量内存,以及 mysqldump 构建输出所需的少量内存。
mysqldump -h $HOST -u $UNAME -p$PWORD --single-transaction $1
在 Linux/Unix 平台上,管道将仅使用足够的内存来阻止缓冲数据到 gzip。gzip 将缓冲一些数据以使其能够优化压缩。更高的压缩值可能会缓冲更多数据,并且需要更多 CPU。mysqldump 中的数据具有高度可压缩性,因为输出中有较长的重复字符串。
| gzip -5
重定向将再次阻止缓冲区数据,然后再将其写入磁盘。其中大部分将使用记录为缓冲区的内存。现代文件系统可能会将数据在内存中保留几秒钟,然后再将数据刷新到磁盘。
> $2_`日期+%d`.sql.gz
数据缓冲区在写入后将保留在池中。如果系统需要空闲内存,这些块将很快被回收。我使用过需要几天时间才能将内存填满到需要回收数据缓冲区的程度的系统。虽然看起来您使用的内存略多于可用内存的一半(不包括缓冲区和缓存),但缓冲区和缓存对性能的贡献很大。
如果这种情况全部发生在一台服务器上,这可能会强制将 mysql 文件中的块移出缓冲池。当请求读取时,这些块将从内存而不是磁盘提供。这可能会降低 mysql 性能,直到块被替换。但是,在远程系统上,主动读取的块可能会在数据被读入内存时被强制移出。