# 管理复制节点

<!-- example managing replication nodes 1 -->
`ALTER CLUSTER <cluster_name> UPDATE nodes` 语句将每个节点内的指定集群中的节点列表更新为包括集群中的所有活动节点。有关节点列表的更多信息，请参见[加入集群](../../Creating_a_cluster/Setting_up_replication/Joining_a_replication_cluster.md)。


<!-- intro -->
##### SQL：

<!-- request SQL -->

```sql
ALTER CLUSTER posts UPDATE nodes
```

<!-- request JSON -->

```json
POST /cli -d "
ALTER CLUSTER posts UPDATE nodes
"
```

<!-- request PHP -->

```php
$params = [
  'cluster' => 'posts',
  'body' => [
     'operation' => 'update',

  ]
];
$response = $client->cluster()->alter($params);
```
<!-- intro -->
##### Python：

<!-- request Python -->

```python
utilsApi.sql('ALTER CLUSTER posts UPDATE nodes')
```

<!-- response Python -->
```python
{u'error': u'', u'total': 0, u'warning': u''}
```

<!-- intro -->
##### Python-asyncio：

<!-- request Python-asyncio -->

```python
await utilsApi.sql('ALTER CLUSTER posts UPDATE nodes')
```

<!-- response Python-asyncio -->
```python
{u'error': u'', u'total': 0, u'warning': u''}
```

<!-- intro -->
##### Javascript：

<!-- request javascript -->

```javascript
res = await utilsApi.sql('ALTER CLUSTER posts UPDATE nodes');
```

<!-- response javascript -->
```javascript
{"total":0,"error":"","warning":""}
```

<!-- intro -->
##### java：

<!-- request Java -->

```java
utilsApi.sql("ALTER CLUSTER posts UPDATE nodes");
```

<!-- intro -->
##### C#：

<!-- request C# -->

```clike
utilsApi.Sql("ALTER CLUSTER posts UPDATE nodes");
```

<!-- intro -->
##### Rust：

<!-- request Rust -->

```rust
utils_api.sql("ALTER CLUSTER posts UPDATE nodes", Some(true)).await;
```

<!-- end -->

如果启用了[身份验证和授权](../../Security/Authentication_and_authorization.md)，`ALTER CLUSTER ... UPDATE nodes`、`ALTER CLUSTER ... ADD` 和 `ALTER CLUSTER ... DROP` 会使用已存储的集群用户。要更改已存储的集群用户，请为新用户授予 `replication` 权限并运行：

```sql
ALTER CLUSTER posts UPDATE user 'repl_user'
```

新的已存储用户必须在后续参与集群操作的节点上配置匹配的身份验证数据。如果已存储用户缺失、身份验证数据不同，或者失去了 `replication` 权限，这些操作都会失败。

例如，当集群最初建立时，用于重新加入集群的节点列表是 `10.10.0.1:9312,10.10.1.1:9312`。此后，其他节点加入了集群，现在活动节点是 `10.10.0.1:9312,10.10.1.1:9312,10.15.0.1:9312,10.15.0.3:9312`。然而，用于重新加入集群的节点列表没有更新。

要纠正这一点，可以运行 `ALTER CLUSTER ... UPDATE nodes` 语句将活动节点列表复制到用于重新加入集群的节点列表。这样，用于重新加入集群的节点列表将包括集群中的所有活动节点。

两个节点列表都可以通过使用 [集群状态](../../Creating_a_cluster/Setting_up_replication/Replication_cluster_status.md) 语句 (`cluster_post_nodes_set` 和 `cluster_post_nodes_view`) 查看。

## 从集群中移除节点

要从复制集群中移除节点，请按照以下步骤操作：
1. 停止节点
2. 从已停止节点的 `<data_dir>/manticore.json`（通常是 `/var/lib/manticore/manticore.json`）中删除集群信息。
3. 在集群中的其他节点上运行 `ALTER CLUSTER cluster_name UPDATE nodes`。

完成这些步骤后，其他节点将忘记已分离的节点，而已分离的节点将忘记集群。此操作不会影响集群中的表或已分离节点上的表。

## EXIT CLUSTER

`EXIT CLUSTER <cluster_name>` 是上述手动脱离流程的在线等效操作。它会将本地节点从复制集群中移除，保留本地表作为常规本地表，保存本地配置，然后要求其他存活节点使用现有的 `ALTER CLUSTER ... UPDATE nodes` 机制刷新其持久化的节点列表。

```sql
EXIT CLUSTER posts
```

当您只想脱离当前节点时，请使用 `EXIT CLUSTER`。当您想从每个节点移除集群时，请使用 `DELETE CLUSTER`。

`EXIT CLUSTER` 仅允许在主集群中的健康本地节点上执行。如果命令返回警告，本地脱离已成功，但可能仍需要后续操作。在这种情况下，在任何存活节点上运行 `ALTER CLUSTER <cluster_name> UPDATE nodes` 以完成刷新剩余集群元数据的操作。

如果幸存的一侧在执行 `EXIT CLUSTER` 后变成了一个干净的单节点集群，它仍然是一个复制集群。干净关闭后，这个幸存节点可以按正常方式启动，并且应当返回为 `primary` / `synced`；在这种仅包含自身的情况下，你不需要使用 `--new-cluster`。
<!-- proofread -->
