icu*_*ken 5 postgresql postgresql-9.6
我试图找出PostgreSQL对磁盘施加了多大的压力,结果到目前为止令人沮丧.请看一下方法论,显然我错过了一些东西或以错误的方式计算数字.
PostgreSQL 9.6.0-1.pgdg16.04 + 1在一个单独的LXC容器内运行,Ubuntu 16.04.1 LTS(内核版本4.4.0-38-通用,SSD上的ext4文件系统),只有一个客户端连接来自我运行测试.
我禁用autovacuum以防止不必要的写入.写入字节的计算是通过以下命令完成的,我想查找所有PostgreSQL进程(包括WAL编写器)写入的总字节数:
pgrep postgres | xargs -I {} cat /proc/{}/io | grep ^write_bytes | cut -d' ' -f2 | python -c "import sys; print sum(int(l) for l in sys.stdin)"
Run Code Online (Sandbox Code Playgroud)
使用#符号我标记了一个数据库命令,?在数据库命令之后我标记了write_bytes sum的结果.测试用例很简单:只有一int4列填充10000000值的表.
在每次测试之前,我运行一组命令来释放磁盘空间并防止其他写入:
# DELETE FROM test_inserts;
# VACUUM FULL test_inserts;
# DROP TABLE test_inserts;
Run Code Online (Sandbox Code Playgroud)
正如文档所述,UNLOGGED表中的更改不会写入WAL日志,因此这是一个很好的开始:
# CREATE UNLOGGED TABLE test_inserts (f1 INT);
? 1526276096
# INSERT INTO test_inserts SELECT generate_series(1, 10000000);
? 1902977024
Run Code Online (Sandbox Code Playgroud)
差异是376700928字节(~359MB),这是有意义的(千万个4字节整数+行,页面和其他成本),但仍然看起来有点太多,几乎是实际数据大小的10倍.
# CREATE UNLOGGED TABLE test_inserts (f1 INT PRIMARY KEY);
? 2379882496
# INSERT INTO test_inserts SELECT generate_series(1, 10000000);
? 2967339008
Run Code Online (Sandbox Code Playgroud)
差异是587456512字节(~560MB).
# CREATE TABLE test_inserts (f1 INT);
? 6460669952
# INSERT INTO test_inserts SELECT generate_series(1, 10000000);
? 7603630080
Run Code Online (Sandbox Code Playgroud)
差异已经是1142960128字节(~1090MB).
# CREATE TABLE test_inserts (f1 INT PRIMARY KEY);
? 12740534272
# INSERT INTO test_inserts SELECT generate_series(1, 10000000);
? 14895218688
Run Code Online (Sandbox Code Playgroud)
现在差异是2154684416字节(~2054MB),大约30秒后写入额外的100MB.
对于这个测试用例,我按流程进行了细分:
Process | Bytes written
/usr/lib/postgresql/9.6/bin/postgres | 0
\_ postgres: 9.6/main: checkpointer process | 99270656
\_ postgres: 9.6/main: writer process | 39133184
\_ postgres: 9.6/main: wal writer process | 186474496
\_ postgres: 9.6/main: stats collector process | 0
\_ postgres: 9.6/main: postgres testdb [local] idle | 1844658176
Run Code Online (Sandbox Code Playgroud)
关于如何衡量我正在寻找的价值观的任何想法,建议?也许这是一个内核错误?或者PostgreSQL真的做了这么多的写作?
编辑:要仔细检查write_bytes是什么意思,我写了一个简单的python脚本证明,这个值是实际写入的字节值.
编辑2:对于PostgreSQL 9.5测试用例#1显示362577920字节,测试#4显示2141343744字节,所以它不是关于PG版本.
编辑3: Richard Huxton提到数据库页面布局文章,我想详细说明:我同意存储成本,包括24个字节的行标题,4个字节的数据本身,甚至4个字节用于数据对齐(通常为8个字节) ,每行提供32个字节,并且每行有大约320MB的行数,这是我用测试#1得到的.我可以假设在这种情况下,主键应该与数据大小相同,并且测试#4(数据和PK)都将写入WAL.这给了360MB x 4 = 1.4GB,这比我得到的结果要差.
| 归档时间: |
|
| 查看次数: |
682 次 |
| 最近记录: |