Eon 模式数据库中的数据完整性和高可用性

Eon 模式数据库的 主子群集中的节点负责维护数据库中的数据。这些节点(统称为数据库的 主节点)计划用于管理分片中数据的 Tuple Mover 合并操作。如果它们是执行这些操作的最佳候选者,它们也可以执行这些操作(请参阅 Eon 模式数据库中的 Tuple Mover)。

主节点可以分布在多个主子群集中 - 它们一起协同工作以维护分片中的数据。主节点的运行状况是数据库继续正常运行的关键。

辅助子群集中的节点不计划 Tuple Mover 操作。如果主节点将 Tuple Mover 分配给它们,它们也可以执行 Tuple Mover 合并操作。您的数据库群集可能会丢失其所有辅助节点,但仍会维护分片中的数据。

维护数据完整性是数据库的首要目标。如果数据库丢失了太多主节点,将无法安全地处理数据。在这种情况下,它会进入只读模式,以防止数据不一致或损坏。

高可用性(即使个别节点丢失,数据库也能继续运行)是 Vertica 的另一个目标。它具有多种冗余功能,可帮助其防止停机。启用这些功能后,即使数据库丢失一个或多个主节点,它仍会继续运行。

数据库继续正常运行有两个要求:维护仲裁和维护分片覆盖率。

维护仲裁

对于 Eon 模式数据库中的主节点,基本要求是维护主节点的 仲裁始终运行。为了维护仲裁,必须有一半以上的主节点(50% 加 1)处于运行状态。例如,在具有 6 个主节点的数据库中,必须至少有 4 个主节点处于运行状态。如果一半或更多主节点关闭,数据库将进入只读模式,以防止潜在的数据完整性问题。在具有 6 个主节点的数据库中,如果数据库丢失 3 个或更多主节点,则数据库将进入只读状态。请参阅下面的只读模式

Vertica 在确定数据库是否具有仲裁时,仅对当前属于数据库的主节点进行计数。移除主节点不会导致仲裁丢失。在移除过程中,Vertica 会调整节点计数以防止丢失仲裁。

Eon 模式数据库必须至少有一个主节点才能运行。在大多数情况下,它需要多个主节点。请参阅下面的 Eon 模式数据库操作的最低节点要求

维护分片覆盖率

为了继续处理数据,数据库必须能够维护其分片中的数据。要维护数据,每个分片必须有一个订阅主节点,负责在其上运行 Tuple Mover。此要求称为具有分片覆盖率。如果一个或多个分片没有主节点维护其数据,则数据库将丢失分片覆盖率并进入只读模式(如下所述),以防止可能出现数据完整性问题。

衡量 Eon 模式数据库对主节点丢失有多大弹性的度量指标称为 K-safety 级别。K 值是 Eon 模式数据库群集维护的冗余分片订阅数。它还表示数据库中可以发生故障但仍能够安全运行的主节点的数量。在许多情况下,数据库可能会丢失超过 K 个节点,但仍然可以继续正常运行,只要它维护分片覆盖率。

Vertica 建议始终将数据库的 K-safety 值设置为 1 (K=1)。在 K=1 的数据库中,每个分片都有两个订户:一个负责分片的主订户,另一个是在主订户丢失时可以补位的辅助订户。主订户负责对分片中的数据运行 Tuple Mover。辅助订户维护分片编录元数据的副本。以便在主订户丢失时可以补位。

如果分片的主订户失败,则辅助订户会补位主订户。因为它没有为其辅助订阅维护单独的存储库,所以辅助订户始终直接访问公共存储中的分片数据。在辅助订户补位主订户时,这种直接访问会影响数据库的性能。因此,请始终尽快重新启动或替换已关闭的主节点。

对于 K=1 数据库中的主订户和辅助订户,丢失单个主节点不会影响数据库处理和维护数据的能力。但是,如果辅助订户在补位主订户时失败,则数据库将丢失分片覆盖率,并被迫进入只读模式。

弹性 K-safety

Vertica 使用一种称为弹性 K-safety 的功能来帮助限制分片覆盖率丢失的可能性。默认情况下,如果分片的主订户或辅助订户失败,Vertica 会为该分片订阅一个额外的主节点。建立此订阅需要一些时间,因为新订阅的节点必须获取分片元数据的副本。如果分片的唯一订户在新订户获取分片元数据时失败,则数据库将丢失分片覆盖率并可能关闭。一旦新订阅的节点获得元数据的副本,它就能够在另一个订户失败时接管分片的维护。此时,您的数据库再次拥有两个分片订户。

一旦关闭的节点恢复并重新加入子群集,Vertica 便会移除它为弹性 K-safety 添加的订阅。所有节点重新加入群集后,分片订阅将与节点丢失之前相同。

借助弹性 K-safety,您的数据库便可以在逐渐丢失主节点直至丢失仲裁的过程中设法维护分片覆盖率。只要新订阅的节点有足够的时间收集分片的元数据,您的数据库便能够维护分片覆盖率。但是,如果在新的主节点完成订阅分片的过程之前,数据库失去了分片的主订户和辅助订户,那么数据库仍然可能由于分片覆盖率丢失而被迫进入只读模式。

数据库只读模式

如果数据库丢失仲裁或主分片覆盖率,它将进入只读模式。此模式可防止当太多节点关闭或无法访问数据库中的其他节点时可能导致的潜在数据损坏。只读模式可防止对数据库进行需要更新全局编录的更改。

只读模式下的 DML 和 DDL

在只读模式下,更改全局编录的语句(例如大多数 DML 和 DDL 语句)会失败,并显示错误消息。例如,当数据库处于只读模式时执行 CREATE TABLE 等 DDL 语句会导致以下错误:

=> CREATE TABLE t (a INTEGER, b VARCHAR);
ERROR 10428:  Transaction commit aborted since the database is currently in read-only mode
HINT:  Commits will be restored when the database restores the quorum

COPY 等 DML 语句返回不同的错误。Vertica 会在它们执行任何工作之前停止它们的执行:

=> COPY warehouse_dimension from stdin;
ERROR 10422:  Running DML statements is not possible in read-only mode
HINT:  Running DMLs will be restored when the database restores the quorum

通过提前返回错误,Vertica 可避免执行加载数据所需的所有工作,在尝试提交事务时便会失败。

不影响全局编录的 DDL 和 DML 语句仍然有效。例如,在数据库处于只读模式时,可以创建一个本地临时表并将数据加载到其中。

只读模式下的查询

查询可以在具有分片覆盖率的任何子群集上运行。例如,假设您有一个 Eon 模式数据库,其中包含一个 3 节点主子群集和一个 3 节点辅助子群集。如果两个主节点出现故障,数据库将丢失仲裁并进入只读模式。主子群集也会丢失分片覆盖率,因为它的两个节点已关闭。剩余的一个节点没有订阅至少部分分片。在这种情况下,剩余主节点上的查询(某些系统表查询除外)始终会失败:

=> SELECT * FROM warehouse_dimension;
ERROR 9099:  Cannot find participating nodes to run the query

辅助子群集仍然具有分片覆盖率,因此可以对其执行查询。

监控只读模式

除了注意到 DML 和 DDL 语句返回错误之外,还可以通过监控系统表来确定数据库是否已进入只读模式:

  • NODES 系统表具有一个名为 is_readonly 的列,当数据库处于只读模式时,该列对所有节点都变为 true。

    => SELECT node_name, node_state, is_primary, is_readonly, subcluster_name FROM nodes;
    
          node_name       | node_state | is_primary | is_readonly |  subcluster_name
    ----------------------+------------+------------+-------------+--------------------
     v_verticadb_node0001 | UP         | t          | t           | default_subcluster
     v_verticadb_node0002 | DOWN       | t          | t           | default_subcluster
     v_verticadb_node0003 | DOWN       | t          | t           | default_subcluster
     v_verticadb_node0004 | UP         | f          | t           | analytics
     v_verticadb_node0005 | UP         | f          | t           | analytics
     v_verticadb_node0006 | UP         | f          | t           | analytics
    (6 rows)
    
  • 当数据库进入只读模式时,数据库中仍在运行的每个节点都会记录一个群集只读事件(事件代码 20)。您可以通过查询事件监控系统表(例如 ACTIVE_EVENTS)找到这些事件:

    => \x
    Expanded display is on.
    
    => SELECT * FROM ACTIVE_EVENTS WHERE event_code = 20;
    -[ RECORD 1 ]-------------+--------------------------------------------------------------------------
    node_name                 | v_verticadb_node0001
    event_code                | 20
    event_id                  | 0
    event_severity            | Critical
    event_posted_timestamp    | 2021-11-22 15:57:24.514475+00
    event_expiration          | 2089-12-10 19:11:31.514475+00
    event_code_description    | Cluster Read-only
    event_problem_description | Cluster cannot perform updates due to quorum loss and can only be queried
    reporting_node            | v_verticadb_node0001
    event_sent_to_channels    | Vertica Log
    event_posted_count        | 1
    -[ RECORD 2 ]-------------+--------------------------------------------------------------------------
    node_name                 | v_verticadb_node0004
    event_code                | 20
    event_id                  | 0
    event_severity            | Critical
    event_posted_timestamp    | 2021-11-22 15:57:24.515022+00
    event_expiration          | 2089-12-10 19:11:31.515022+00
    event_code_description    | Cluster Read-only
    event_problem_description | Cluster cannot perform updates due to quorum loss and can only be queried
    reporting_node            | v_verticadb_node0004
    event_sent_to_channels    | Vertica Log
    event_posted_count        | 1
    -[ RECORD 3 ]-------------+--------------------------------------------------------------------------
    node_name                 | v_verticadb_node0005
    event_code                | 20
    event_id                  | 0
    event_severity            | Critical
    event_posted_timestamp    | 2021-11-22 15:57:24.515019+00
    event_expiration          | 2089-12-10 19:11:31.515019+00
    event_code_description    | Cluster Read-only
    event_problem_description | Cluster cannot perform updates due to quorum loss and can only be queried
    reporting_node            | v_verticadb_node0005
    event_sent_to_channels    | Vertica Log
    event_posted_count        | 1
    -[ RECORD 4 ]-------------+--------------------------------------------------------------------------
    node_name                 | v_verticadb_node0006
    event_code                | 20
    event_id                  | 0
    event_severity            | Critical
    event_posted_timestamp    | 2021-11-22 15:57:24.515172+00
    event_expiration          | 2089-12-10 19:11:31.515172+00
    event_code_description    | Cluster Read-only
    event_problem_description | Cluster cannot perform updates due to quorum loss and can only be queried
    reporting_node            | v_verticadb_node0006
    event_sent_to_channels    | Vertica Log
    event_posted_count        | 1
    

    请参阅监控事件

从只读模式恢复

要从只读模式恢复,请重新启动关闭的节点。重新启动节点即可解决导致数据库进入只读模式的仲裁丢失或主分片覆盖率丢失的问题。

一旦关闭的节点重新启动并重新加入数据库,Vertica 便会在处于只读模式的节点上重新启动。为了让节点能够重新订阅其分片,必须执行此步骤。在此重新启动期间,与这些节点的客户端连接将断开。例如,通过 vsql 连接到 Vertica 正在重新启动的节点之一的用户会看到以下消息:

server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.

在 Vertica 重新启动时,使用 vsql 连接到节点的用户会看到以下消息:

vsql: FATAL 4149:  Node startup/recovery in progress. Not yet ready
to accept connections

Vertica 在节点上重新启动后,数据库将恢复正常运行。

当 Vertica 在 Eon 模式数据库中设置 K-safety 值时

当您的数据库中有三个或更多主节点时,Vertica 会自动将数据库的 K-safety 设置为 1 (K=1)。它还会自动配置分片订阅,以便每个节点都可以充当另一个节点的备份,如维护分片覆盖率中所述。

此行为与企业模式数据库不同,在企业模式数据库中,您必须设计数据库的物理架构以满足多个标准,然后才能让 Vertica 将数据库标记为 K-safe。有关详细信息,请参阅下面的企业模式和 Eon 模式 K-safe 设计之间的差异

Eon 模式数据库操作的最低节点要求

数据库的 K-safety 级别决定了它必须具有的最小主节点数:

  • 当 K=0 时,数据库必须至少具有 1 个主节点。将 K 设置为 0 允许您拥有单节点 Eon 模式数据库。请注意,在 K=0 数据库中,主节点丢失将导致数据库进入只读模式。
  • 当 K=1(最常见的情况)时,数据库必须至少具有三个主节点。此数量的主节点让 Vertica 能够在主节点出现故障时维护数据完整性。
  • 如果要手动将 K-safe 值设置为 2(请参阅下面的企业模式和 Eon 模式 K-safe 设计之间的差异),则必须至少具有 5 个主节点。

如果群集将会低于数据库 K-safety 设置的下限,Vertica 会阻止您移除主节点。如果要移除处于此下限的数据库中的节点,则必须使用 MARK_DESIGN_KSAFE 函数降低 K-safety 级别,然后调用 REBALANCE_SHARDS

关键节点和子群集

Vertica 将数据库中丢失便会导致数据库进入只读模式的任何节点或子群集指定为关键节点或子群集。例如,在 Eon 模式数据库中,当主节点出现故障时,对其分片具有辅助订阅的节点将接管分片的数据维护。这些节点变为关键节点。它们的丢失将导致数据库丢失分片覆盖率,并被迫进入只读模式。

Vertica 在两个系统表中维护关键节点和子群集列表: CRITICAL_NODESCRITICAL_SUBCLUSTERS。在停止节点或子群集之前,请检查这两个表以确保要停止的节点或子群集不是关键节点或子群集。

企业模式和 Eon 模式 K-safe 设计之间的差异

在企业模式数据库中,可以使用 MARK_DESIGN_KSAFE 函数在数据库中启用高可用性。在设计了数据库的物理架构以满足 K-safe 设计的所有要求(通常,通过运行 Database Designer)之后,便可以调用此函数。如果在物理架构不支持传递给 MARK_DESIGN_KSAFE 的 K-safety 级别时尝试将数据库标记为 K-safe,则会返回错误。有关详细信息,请参阅为 K-safety 安全设计分段投影

在 Eon 模式下,您不需要使用 MARK_DESIGN_KSAFE,因为当您具有三个或更多主节点时,Vertica 会自动将数据库设置为 K-safe。您可以使用此函数更改数据库的 K-safety 级别。在 Eon 模式数据库中,此函数更改 Vertica 配置分片订阅的方式。您可以使用所需的任何 K-safety 级别调用 MARK_DESIGN_KSAFE。仅当您调用 REBALANCE_SHARDS 来更新数据库中节点的分片订阅时,它才会生效。