跟踪写入临时表的字节数

时间:2016-10-12 17:32:02

标签: postgresql

使用PostgreSQL 9.5,我想跟踪写入的总字节数(自数据库集群启动以来):

  1. WAL
  2. 临时文件
  3. 临时表
  4. 1:

    select
       pg_size_pretty(archived_count * 16*1024*1024) temp_bytes,
       (now() - stats_reset)::text uptime
    from pg_stat_archiver;
    

    2:

    select
       (now() - stats_reset)::text uptime,
       pg_size_pretty(temp_bytes) temp_bytes
    from pg_stat_database where datname = 'mydb';
    

    我如何获得3?

    在回复下面的评论时,我做了一些测试来检查实际写入temp tables 的位置。

    首先,此群集上的数据库参数temp_buffers为8GB:

    select pg_size_pretty(setting::bigint*8192) from pg_settings
         where name = 'temp_buffers';
    -- "8192 MB"
    

    让我们创建一个临时表:

    drop table if exists foo;
    
    create temp table foo as
    select random() from generate_series(1, 1000000000);
    -- Query returned successfully: 1000000000 rows affected, 10:22 minutes execution time.
    

    检查创建的临时表的PostgreSQL后端pid和OID:

    select pg_backend_pid(), 'pg_temp.foo'::regclass::oid;
    -- 46573;398695055
    

    检查后端进程的RSS大小

    ~$ grep VmRSS /proc/46573/status
    VmRSS:   9246276 kB
    

    可以看出,这仅略高于temp_buffers的8GB设置。

    然而,插入到临时表中的数据立即写入,并将其写入正常的表空间目录,而不是临时文件:

    select * from pg_relation_filepath('pg_temp.foo')
    -- "base/16416/t3_398695055"
    

    以下是文件数量和写入金额:

    with temp_table_files as
    (
        select * from pg_ls_dir('base/16416/') fn
            where fn like 't3_398695055%'
    )
    select
        count(*) as cnt,
        pg_size_pretty(sum((pg_stat_file('base/16416/' || fn)).size)) as size
    from temp_table_files;
    -- 34;"34 GB"
    

    最后验证此后端PID拥有的temp 文件集合是否为空:

    with temp_files_per_pid as
    (
        with temp_files as
        (
        select
            temp_file,
            (regexp_replace(temp_file, $r$^pgsql_tmp(\d+)\..*$$r$, $rr$\1$rr$, 'g'))::int as pid,
            (pg_stat_file('base/pgsql_tmp/' || temp_file)).size as size
        from pg_ls_dir('base/pgsql_tmp') temp_file
        )
        select pid, pg_size_pretty(sum(size)) from temp_files group by pid order by pid
    )
    select * from temp_files_per_pid where pid = 46573;
    

    什么都不返回。

    删除临时表后,还有什么"有趣"

    DROP TABLE foo;
    

    后端进程的RSS reduce:

    ~$ grep VmRSS /proc/46573/status
    VmRSS:   9254544 kB
    

    执行以下操作也不会再次释放RSS:

    RESET ALL;
    DEALLOCATE ALL;
    DISCARD TEMP;
    

1 个答案:

答案 0 :(得分:1)

据我所知,临时表没有任何特殊指标。临时表使用会话(进程)内存到temp_buffers大小(默认为8MB)。当这些临时缓冲区已满时,将生成临时文件。