RDS PostgreSQL实例的I/O性能受硬件层存储介质、软件层数据库内核架构和具体SQL语句(扫描或修改数据量)的影响。

基本概念

名称 概念
IO Input和Output的缩写,即对磁盘进行的读写动作。
IO延时 一个读写操作的执行时间。
逻辑IO 由应用程序发给文件系统的读写操作。
物理IO 由文件系统发给磁盘的读写操作。
顺序IO 按照顺序向磁盘进行读写操作。
随机IO 随机向磁盘进行读写操作。
同步写 等待数据完全写入磁盘后再返回,会阻塞程序直到写入完成。
异步写 不等待数据写入结束直接返回,不会阻塞程序。

SQL扫描行高导致实例I/O高

  • 现象:

    数据盘IOPS中发现读占用较高,正常情况下客户端使用SQL访问的数据都是从共享缓冲区返回的,共享缓冲区中未命中的数据会从磁盘中读取,读占用高说明数据大量从磁盘读取到共享缓冲区,因此推断可能存在SQL扫描行较高的情况。

    说明 您可以在控制台的监控与报警 > 标准监控页面中查看各项监控指标。
    数据盘IOPS

    操作行数中发现全表扫描行明显增加,说明客户端读取了大量的数据。

    操作行数
  • 解决方案:

    通过性能洞察找到对应的问题SQL,针对该问题SQL进行索引优化或者增加实例规格以承担更高的负载。

    说明 您可以在控制台的自治服务 > 一键诊断页面,单击性能洞察页签使用性能洞察功能。

导入数据导致实例I/O高

  • 现象:

    数据盘IOPS中发现写占用较高,怀疑存在大量的数据导入动作。

    说明 您可以在控制台的监控与报警 > 标准监控页面中查看各项监控指标。
    数据盘IOPS2
  • 解决方案:通过性能洞察发现是因为导入数据导致的IOPS升高,应尽量避免业务高峰期的数据导入操作。

Vacuum操作导致实例I/O高

Vacuum指的是PostgreSQL实例对垃圾数据进行的清理动作,在执行UPDATEDELETE的过程中,数据表会产生垃圾数据,需要及时通过Vacuum进行清理回收空间。

  • 现象:

    数据盘IOPS中发现读写操作均占用了较多的资源,并且操作行数中未见明显增加的趋势,此时怀疑是Vacuum或者是CheckPoint引起的IOPS升高。

    说明 您可以在控制台的监控与报警 > 标准监控页面中查看各项监控指标。
    数据盘IOPS3操作行数2
    通过select * from pg_stat_progress_vacuum ;语句查询pg_stat_progress_vacuum可以看到当前正在运行的Vacuum动作以及进度,可以确定是由Vacuum引起的IOPS升高。
    -[ RECORD 1 ]------+--------------
    pid                | 109229
    datid              | 13593
    datname            | postgres
    relid              | 40435
    phase              | scanning heap
    heap_blks_total    | 943453
    heap_blks_scanned  | 937101
    heap_blks_vacuumed | 0
    index_vacuum_count | 0
    max_dead_tuples    | 291
    num_dead_tuples    | 0
    通过select * from pg_stat_user_tables where relname ='t_all';语句还可以查询到Vacuum的历史执行情况。
    -[ RECORD 1 ]-------+------------------------------
    relid               | 40435
    schemaname          | public
    relname             | t_all
    seq_scan            | 4547
    seq_tup_read        | 35959634448
    idx_scan            |
    idx_tup_fetch       |
    n_tup_ins           | 91514896
    n_tup_upd           | 0
    n_tup_del           | 0
    n_tup_hot_upd       | 0
    n_live_tup          | 91514896
    n_dead_tup          | 0
    n_mod_since_analyze | 0
    last_vacuum         | 2020-11-20 14:25:19.077927+08
    last_autovacuum     |
    last_analyze        |
    last_autoanalyze    | 2020-11-20 11:59:34.641906+08
    vacuum_count        | 1
    autovacuum_count    | 0
    analyze_count       | 0
    autoanalyze_count   | 5
  • 解决方案:

    在控制台的参数设置中根据实际业务场景调整Vacuum相关参数降低Vacuum对I/O产生的影响。

    调整Vacuum参数
    • autovacuum_vacuum_cost_delay:vacuum进程的代价达到autovacuum_vacuum_cost_limit设置的值时,vacuum进程暂停的时间。单位为ms。
    • autovacuum_vacuum_cost_limit:评估vacuum进程代价的阈值。
    注意 Vacuum回收速度过慢也会导致更加严重的表膨胀。

CheckPoint操作导致实例I/O高

  • 现象:
    通过select * from pg_stat_bgwriter ;语句查询pg_stat_bgwriter,分析checkpoints_req指标。该指标指的是手动CheckPoint以及wal日志写入量达到max_wal_size的次数。可以发现此时checkpoints_req的值为160。
    -[ RECORD 1 ]---------+------------------------------
    checkpoints_timed     | 8271
    checkpoints_req       | 160
    checkpoint_write_time | 9109283
    checkpoint_sync_time  | 22878
    buffers_checkpoint    | 1228674
    buffers_clean         | 829714
    maxwritten_clean      | 293
    buffers_backend       | 3731358
    buffers_backend_fsync | 0
    buffers_alloc         | 2290169
    stats_reset           | 2020-06-28 15:32:00.021466+08
  • 解决方案:

    关注是否有大批量导入的情况,建议控制批量导入的大小,建议调整为小批量,分多次导入以减小I/O的压力。

说明 CheckPoint指的是将数据库共享缓冲区的脏页写入到磁盘的操作,如下四种情况会触发CheckPoint操作:
  • 定时触发:通过checkpoint_timeout参数定时将数据库共享缓冲区的脏页进行写入到磁盘,此行为为异步写,数据分多次小批量写入磁盘,对I/O影响小。
  • wal日志写入量达到max_wal_size时触发:wal日志是循环使用的,当日志量达到max_wal_size,会触发积极的CheckPoint,此行为为同步写,会全速进行数据写入动作,对I/O影响大。
  • 手动CheckPoint:此行为为同步写,会全速进行数据写入动作,对I/O影响大。
  • 重启实例:此行为为同步写,会全速进行数据写入动作,对I/O影响大。