AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 237846
Accepted
dw8547
dw8547
Asked: 2019-05-11 07:01:55 +0800 CST2019-05-11 07:01:55 +0800 CST 2019-05-11 07:01:55 +0800 CST

添加 JSONB 索引是否会使数据库膨胀?

  • 772

我们正在运行:

user@host:~$ psql -d database -c "SELECT version();"                                                                   
version
---------------------------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 10.7 (Ubuntu 10.7-1.pgdg16.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609, 64-bit
(1 row)

上:

user@host:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:    16.04
Codename:   xenial

并具有以下设置:

database=# \d+ schema.table
                                                                  Table "schema.table"
           Column            |            Type             | Collation | Nullable |                     Default                     | Storage  | Stats target | Description
-----------------------------+-----------------------------+-----------+----------+-------------------------------------------------+----------+--------------+-------------
 column_1                    | bigint                      |           | not null | nextval('table_id_seq'::regclass)               | plain    |              |
 column_2                    | character varying           |           | not null |                                                 | extended |              |
 column_3                    | character varying           |           | not null |                                                 | extended |              |
 column_4                    | character varying           |           | not null |                                                 | extended |              |
 column_5                    | timestamp without time zone |           | not null |                                                 | plain    |              |
 column_6                    | timestamp without time zone |           |          |                                                 | plain    |              |
 column_7                    | character varying           |           | not null |                                                 | extended |              |
 column_8                    | jsonb                       |           | not null |                                                 | extended |              |
 column_9                    | jsonb                       |           |          |                                                 | extended |              |
 column_10                   | character varying           |           | not null |                                                 | extended |              |
 column_11                   | character varying           |           | not null |                                                 | extended |              |
 column_12                   | character varying           |           |          |                                                 | extended |              |
 column_13                   | character varying           |           |          |                                                 | extended |              |
 column_14                   | timestamp with time zone    |           | not null |                                                 | plain    |              |
 column_15                   | timestamp with time zone    |           | not null |                                                 | plain    |              |
Indexes:
    "table_pkey" PRIMARY KEY, btree ( column_1 )
    "table_idx_1" btree ( column_11)
    "table_idx_2" btree ( column_4, column_2, column_7, column_5, column_6 )
    "table_idx_3" btree ( column_7, column_11, column_15 )
    "table_idx_4" btree ( column_7, column_11, column_14 )
    "table_idx_5" btree ( column_7, column_11, column_5 )
    "table_idx_6" btree ( column_7, ( ( column_8 ->> 'string_1'::TEXT )::INTEGER ), column_5 )
    "table_idx_7" btree ( column_15 )
    "table_idx_8" btree ( column_4, column_2, column_7, column_5, ( ( column_8 ->> 'string_1'::TEXT )::INTEGER ) )
    "table_idx_9" btree ( column_4, column_2, column_7, ( ( column_8 ->> 'string_1'::TEXT )::INTEGER) )
    "table_idx_a" btree ( column_7, column_4, column_2, ( ( column_8 ->> 'string_1'::TEXT )::INTEGER), ( ( column_8 ->> 'string_2'::TEXT )::INTEGER ) ) WHERE column_7::TEXT = 'string_3'::TEXT
Check constraints:
    "table_check_constraints" CHECK ( lower( column_10::TEXT ) <> 'string_4'::TEXT OR column_9 IS NOT NULL AND column_6 IS NOT NULL )

Autovacuum 已打开并配置为:

user@host:~$ psql -d database -c "SELECT name, setting, pending_restart FROM pg_settings WHERE NAME ILIKE '%autovacuum%' ORDER BY name;"
                name                 |  setting              | pending_restart
-------------------------------------+-----------------------+-----------------
 autovacuum                          | on                    | f
 autovacuum_analyze_scale_factor     | 0.002                 | f
 autovacuum_analyze_threshold        | 10                    | f
 autovacuum_freeze_max_age           | 200000000             | f
 autovacuum_max_workers              | 5                     | f
 autovacuum_multixact_freeze_max_age | 400000000             | f
 autovacuum_naptime                  | 30                    | f
 autovacuum_vacuum_cost_delay        | 10                    | f
 autovacuum_vacuum_cost_limit        | 1000                  | f
 autovacuum_vacuum_scale_factor      | 0.001                 | f
 autovacuum_vacuum_threshold         | 25                    | f
 autovacuum_work_mem                 | -1                    | f
 log_autovacuum_min_duration         | 0 (env 1) /-1 (env 2) | f
(13 rows)

以下事件序列发生在环境 1中,在此期间autovacuum已按上述方式开启和配置:

  1. 每晚VACUUM (VERBOSE, ANALYZE)添加数据库。
  2. 一段时间过去,膨胀处于正常运行水平。
  3. NightlyVACUUM (VERBOSE, ANALYZE)的数据库被删除。
  4. table_idx_8添加了包含 JSONB 数据类型列的索引。
  5. table_idx_9添加了包含 JSONB 数据类型列的索引。
  6. 膨胀的生长突增开始并持续 2 天,直到达到顶峰。
  7. VACUUM (VERBOSE, FULL)的表。
  8. 膨胀恢复到正常的操作水平并保持在那里。

在这一系列事件中,环境 1中的数据库大小 (GB) 如下所示:

环境 1 数据库大小 (GB)

这就是环境 1中膨胀 (GB) 的样子:

环境 1 数据库膨胀 (GB)

环境 1中的活动行数:

环境 1 活动行数

环境 1中的死行数:

环境 1 死行数

以下事件序列发生在环境 2中,在所有这些事件中都autovacuum按上述方式打开和配置:

  1. 每晚VACUUM (VERBOSE, ANALYZE)添加数据库。
  2. 一段时间过去,膨胀处于正常运行水平。
  3. NightlyVACUUM (VERBOSE, ANALYZE)的数据库被删除。
  4. table_idx_8添加了包含 JSONB 数据类型列的索引。
  5. table_idx_9添加了包含 JSONB 数据类型列的索引。
  6. 膨胀的增长突增开始并持续 2 天,直到达到峰值并使 DB 下降(磁盘已满)。
  7. TRUNCATE TABLE schema.table.
  8. 再次填充 schema.table 表。
  9. 膨胀并没有稳定下来并增长,直到它再次达到顶峰。
  10. TRUNCATE TABLE schema.table在磁盘再次填满之前。
  11. 数据库的 VACUUM (VERBOSE, FULL)。
  12. 再次填充 schema.table 表。
  13. 膨胀继续增长!

在这一系列事件中,环境 2中的数据库大小 (GB)如下所示:

在此处输入图像描述

这就是环境 2中膨胀 (GB) 的样子:

在此处输入图像描述

这两种环境之间的唯一区别是它们的规格略有不同(2 的功能较弱)。在这些事件序列中,每个环境的写入/读取量都没有变化。我们正在使用此查询来衡量膨胀(以字节为单位)。

我已经交叉检查了 PostgreSQL 日志、监控日志和提交日志 (Git),并确定添加两个索引作为膨胀的触发器,但是:

  1. 那正确吗?增加一个指数会引发如此膨胀的增长吗?
  2. 如果确实如此,为什么添加索引会触发膨胀?
  3. 为什么环境 1 稳定而环境 2 不稳定?
  4. 我们如何稳定环境 2?

任何回答这些问题的帮助将不胜感激,不用说,我很乐意提供我错过的任何其他可能有用的信息。

postgresql index
  • 1 1 个回答
  • 355 Views

1 个回答

  • Voted
  1. Best Answer
    jjanes
    2019-05-13T07:10:03+08:002019-05-13T07:10:03+08:00

    我认为考古方法在这里不会很有用。缺少太多信息和混淆变量。例如,人们通常不会无缘无故地添加索引。如果工作负载的变化推动了索引的创建,则可能是独立于索引的工作负载的变化导致了膨胀。

    有很多理论可以解释你所看到的,但实际上没有办法根据给出的历史来区分它们。每个索引都为真空提供了更多工作要做,因此您的新索引可能只是因为它已经接近临界点而将其推到了临界点,而不管索引的内容是什么。或者,当表被锁定以创建索引时,可能会堆积很多工作,然后一旦锁定被释放,活动的狂热就会把它推到边缘。不仅仅是更多的索引为真空创造了更多的工作——膨胀也是如此。这可能导致恶性循环,更多的膨胀会减缓真空,导致更多的膨胀。这可能是 VACUUM FULL 后环境 1 稳定的原因,它打破了恶性循环,以至于常规真空现在可以跟上。

     autovacuum_analyze_scale_factor     | 0.002                 | f
     autovacuum_analyze_threshold        | 10                    | f
     autovacuum_vacuum_scale_factor      | 0.001                 | f
     autovacuum_vacuum_threshold         | 25                    | f
    

    乍一看,这些设置似乎相当荒谬。他们有理由吗?它可能会花费大量时间清理和分析并不真正需要它们的表,以至于它无法跟上需要清理的表(但如果你只有一个大表,那可能不是很多关心)。降低比例因子是有意义的,但通常只能与阈值的增加结合使用。

    我经常将“vacuum_cost_page_hit”设置为零“vacuum_cost_page_miss”设置为零。以我的经验,autovac引起的并发性能问题一般是由写入引起的,而不是由读取引起的,因此在读取端进行节流是没有意义的。当您拥有已经膨胀的表和索引时,这一点尤其重要,因为您可以进行更多的阅读而不是写作。

    设置 log_autovacuum_min_duration=0 的输出可以帮助区分各种理论。此外,使用pg_freespacemap来查看 PostgreSQL 认为该表有多少 sum(avail),虽然它处于膨胀状态,但可以提供信息。

    • 3

相关问题

  • 我在索引上放了多少“填充”?

  • PostgreSQL 中 UniProt 的生物序列

  • RDBMS 上的“索引”是什么意思?[关闭]

  • 如何在 MySQL 中创建条件索引?

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve