Aurora DSQL 中的异步索引 - Amazon Aurora DSQL

Amazon Aurora DSQL 作为预览服务提供。要了解更多信息,请参阅《AWS Service Terms》中的 Betas and Previews

Aurora DSQL 中的异步索引

CREATE INDEX ASYNC 命令在指定表的某列上创建索引。CREATE INDEX ASYNC 是一个异步 DDL 操作,因此,此命令不会阻止其它事务。

当您运行此命令时,Aurora DSQL 会立即返回 job_id。您可以随时通过 sys.jobs 系统视图查看异步作业的状态。

当索引创建作业正在进行时,您可以使用以下过程和命令:

sys.wait_for_job(job_id)

阻止该会话,直到指定的作业完成或失败。此过程返回布尔值。

DROP INDEX

取消正在进行的索引构建作业。

当 Aurora DSQL 完成异步索引任务时,它会更新系统目录以显示该索引处于活动状态。如果此时其它事务引用同一命名空间中的对象,则您可能会看到并发错误。

语法

CREATE INDEX ASYNC 使用下面的语法。

CREATE [ UNIQUE ] INDEX ASYNC [ IF NOT EXISTS ] name ON table_name ( { column_name } [ NULLS { FIRST | LAST } ] ) [ INCLUDE ( column_name [, ...] ) ] [ NULLS [ NOT ] DISTINCT ]

参数

UNIQUE

指示 Aurora DSQL 在它创建索引时和您每次添加数据时,检查表中是否存在重复值。如果指定此参数,则会导致重复条目的插入和更新操作会生成错误。

IF NOT EXISTS

指示如果已存在同名的索引,则 Aurora DSQL 不应引发异常。在这种情况下,Aurora DSQL 不会创建新索引。请注意,您尝试创建的索引的结构可能与现有的索引截然不同。如果您指定此参数,则需要索引名称。

name

索引的名称。您不能在此参数中包含架构的名称。

Aurora DSQL 在与其父表相同的架构中创建索引。索引的名称必须与架构中任何其它对象(例如表或索引)的名称不同。

如果您未指定名称,Aurora DSQL 将根据父表和索引列的名称自动生成名称。例如,如果您运行 CREATE INDEX ASYNC on table1 (col1, col2),Aurora DSQL 会自动将索引命名为 table1_col1_col2_idx

NULLS FIRST | LAST

空列和非空列的排序顺序。FIRST 表示 Aurora DSQL 应先对空列进行排序,然后再对非空列进行排序。LAST 表示 Aurora DSQL 应先对非空列进行排序,之后再对空列进行排序。

INCLUDE

要作为非键列包含在索引中的列的列表。您不能在索引扫描搜索限定条件中使用非键列。就索引的唯一性而言,Aurora DSQL 会忽略该列。

NULLS DISTINCT | NULLS NOT DISTINCT

指定 Aurora DSQL 是否应将空值视为唯一索引中的不同值。默认值为 DISTINCT,这意味着唯一索引可以在一列中包含多个空值。NOT DISTINCT 表示索引不能在一列中包含多个空值。

使用说明

请考虑以下准则:

  • CREATE INDEX ASYNC 命令不引入锁。它也不会影响 Aurora DSQL 用来创建索引的基表。

  • 在架构迁移操作期间,sys.wait_for_job(job_id) 过程很有用。它可确保后续的 DDL 和 DML 操作以新创建的索引为目标。

  • 每当 Aurora DSQL 运行新的异步任务时,它都会检查 sys.jobs 视图,并删除状态为 completedfailed 超过 30 分钟的任务。这样,sys.jobs 主要显示正在进行的任务,而不包含有关旧任务的信息。

  • 如果 Aurora DSQL 无法构建异步索引,则索引将保持 INVALID。对于唯一索引,DML 操作受唯一性约束所制约,直至您删除索引。我们建议您删除无效的索引并重新创建它们。

创建索引:示例

以下示例演示如何创建架构、表和索引。

  1. 创建名为 test.departments 的文件。

    CREATE SCHEMA test; CREATE TABLE test.departments (name varchar(255) primary key not null, manager varchar(255), size varchar(4));
  2. 在表中插入一行。

    INSERT INTO test.departments VALUES ('Human Resources', 'John Doe', '10')
  3. 创建异步索引。

    CREATE INDEX ASYNC test_index on test.departments(name, manager, size);

    CREATE INDEX 命令返回作业 ID,如下所示。

    job_id -------------------------- jh2gbtx4mzhgfkbimtgwn5j45y

    job_id 表示 Aurora DSQL 已经提交了新作业来创建索引。可以使用过程 sys.wait_for_job(job_id) 来阻止会话中的其它工作,直到作业完成或超时。

查询索引创建的状态:示例

查询 sys.jobs 系统视图以查看索引的创建状态,如以下示例所示。

SELECT * FROM sys.jobs

Aurora DSQL 返回与下面类似的响应。

job_id | status | details ----------------------------+------------+--------- vs3kcl3rt5ddpk3a6xcq57cmcy | completed | ihbyw2aoirfnrdfoc4ojnlamoq | processing |

状态列可以是以下值之一:

submitted

任务已提交,但是 Aurora DSQL 尚未开始处理该任务。

processing

Aurora DSQL 正在处理该任务。

failed

任务失败。有关更多信息,请参阅详细信息列。如果 Aurora DSQL 未能构建索引,Aurora DSQL 不会自动移除索引定义。您必须使用 DROP INDEX 命令手动移除索引。

completed

Aurora DSQL

也可以通过目录表 pg_indexpg_class 查询索引的状态。具体而言,属性 indisvalidindisimmediate 可以告诉您索引处于什么状态。当 Aurora DSQL 创建索引时,索引的初始状态为 INVALID。索引的 indisvalid 标志返回 FALSEf,表示该索引无效。如果标志返回 TRUEt,则索引已就绪。

select relname as index_name, indisvalid as is_valid, pg_get_indexdef(indexrelid) as index_definition from pg_index, pg_class where pg_class.oid = indexrelid and indrelid = 'test.departments'::regclass;
index_name | is_valid | index_definition ------------------+----------+------------------------------------------------------------------------------------------------------------------- department_pkey | t | CREATE UNIQUE INDEX department_pkey ON test.departments USING btree_index (title) INCLUDE (name, manager, size) test_index1 | t | CREATE INDEX test_index1 ON test.departments USING btree_index (name, manager, size)

查询索引的状态:示例

可以使用目录表 pg_indexpg_class 查询索引的状态。具体来说,属性 indisvalidindisimmediate 告诉您索引的状态。以下示例显示了示例查询和结果。

SELECT relname AS index_name, indisvalid AS is_valid, pg_get_indexdef(indexrelid) AS index_definition FROM pg_index, pg_class WHERE pg_class.oid = indexrelid AND indrelid = 'test.departments'::regclass; index_name | is_valid | index_definition ------------------+----------+------------------------------------------------------------------------------------------------------------------- department_pkey | t | CREATE UNIQUE INDEX department_pkey ON test.departments USING btree_index (title) INCLUDE (name, manager, size) test_index1 | t | CREATE INDEX test_index1 ON test.departments USING btree_index (name, manager, size)

当 Aurora DSQL 创建索引时,索引的初始状态为 INVALID。索引的 indisvalid 列显示 FALSEf,表示该索引无效。如果该列显示 TRUEt,则索引已就绪。

indisunique 标志指示索引为 UNIQUE。要了解表是否要接受并发写入的唯一性检查,请查询 pg_index 中的 indimmediate 列,如下面的查询所示。

SELECT relname AS index_name, indimmediate AS check_unique, pg_get_indexdef(indexrelid) AS index_definition FROM pg_index, pg_class WHERE pg_class.oid = indexrelid AND indrelid = 'test.departments'::regclass; index_name | check_unique | index_definition ------------------+----------+------------------------------------------------------------------------------------------------------------------- department_pkey | t | CREATE UNIQUE INDEX department_pkey ON test.departments USING btree_index (title) INCLUDE (name, manager, size) test_index1 | f | CREATE INDEX test_index1 ON test.departments USING btree_index (name, manager, size)

如果该列显示 f 并且您的作业处于状态 processing,则索引仍在创建中。对索引的写入不受唯一性检查的约束。如果列显示 t 且作业状态为 processing,则已构建初始索引,但尚未对索引中的所有行执行唯一性检查。但是,对于当前和将来对索引的所有写入,Aurora DSQL 将执行唯一性检查。