> For the complete documentation index, see [llms.txt](https://docs.tibero.com/tmaxopensql/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tibero.com/tmaxopensql/administration/etcd.md).

# Etcd 관리

## **개요**

본 문서에서는 ETCD3와 함께 설치되는 명령줄 도구인 `etcdctl` 을 이용한 ETCD3 클러스터의 멤버와 엔드포인트 Health 등 상태를 확인하거나 특정 조건을 만족하는 Key들의 값을 조회하고 클러스터의 읽기 / 쓰기 성능을 테스트하는 방법에 대하여 기술합니다.

***

## **명령줄 도구 etcdctl 설치 확인**

ETCD3 클러스터를 관리하기 위한 명령줄 도구인 `etcdctl` 은 `etcd` 서버 바이너리와 함께 제공됩니다. 노드에 `etcdctl` 이 설치되어 있는지 여부와 버전을 확인할 수 있습니다.

```bash
$ which etcdctl
/usr/local/bin/etcdctl

$ etcdctl version
etcdctl version: 3.5.6
API version: 3.5
```

`etcdctl` 의 API에는 `v2` 와 `v3` 두 개의 버전이 있으며 `etcdctl` 실행 시 환경변수 `ETCDCTL_API` 를 각각 `2` 혹은 `3` 으로 설정하여 어떤 버전의 API를 호출할 지 명시할 수 있습니다.

v3.4.0 이상부터는 `v3` 버전의 API가 기본으로 사용되며 본 문서에서도 `v3` 버전의 API를 기준으로 사용법을 서술합니다.

### **공통 옵션**

`etcdctl` 명령어를 실행할 때 지정할 수 있는 공통 옵션에 대하여 설명합니다.

* `--endpoints` : `etcdctl` 이 접근할 ETCD3 gRPC 서버의 Endpoint URL들을 쉼표 `,` 로 구분된 목록으로 지정합니다. 지정되지 않은 경우 실행되는 환경의 localhost `127.0.0.1:2379` 를 기본 gRPC Endpoint URL로 인지하여 통신을 시도합니다.
  * 유효하지 않은 Endpoint URL은 아래와 같이 에러를 반환합니다.

    ```bash
    $ etcdctl member list
    Error:  dial tcp 127.0.0.1:2379: connect: connection refused
    ```
* `-w, --write-out` : 출력값의 Format을 설정하는 옵션으로 `fields`, `json`, `protobuf`, `simple`, `table` 을 허용합니다.
* `--key` : https 엔드포인트로 접근하려는 경우 TLS 인증에 사용할 Client Key 파일 경로를 지정합니다.
* `--cert` : TLS 인증에 사용할 Client 인증서 파일 경로를 지정합니다.
* `--cacert` : TLS 인증에 사용할 인증기관 (CA) 인증서 파일 경로를 지정합니다.

#### **예시**

```bash
$ ETCDCTL_API=3 etcdctl --endpoints="https://192.168.0.10:2379,https://192.168.0.11:2379" \
  --key="./etcd-client-key.pem" \
  --cert="./etcd-client-crt.pem" \
  --cacert="./etcd-ca-crt.pem" \
  member list
```

{% hint style="info" %}
**참고**

<https://github.com/etcd-io/etcd/issues/9600>
{% endhint %}

***

## **클러스터 상태 조회**

클러스터의 멤버 및 Endpoint URL의 목록과 상태를 조회합니다.

### **클러스터 멤버 조회**

`etcdctl member list` 로 클러스터 노드의 이름, Advertise 된 Peer 통신을 위한 URL 목록과 Client 통신을 위한 URL 목록을 확인할 수 있습니다.

```bash
$ etcdctl member list
670b863301943618, started, node1, http://192.168.0.10:2380, http://192.168.0.10:2379, false
7825d7b04510b842, started, node3, http://192.168.0.11:2380, http://192.168.0.11:2379, false
c8245114d55ec576, started, node2, http://192.168.0.12:2380, http://192.168.0.12:2379, false

$ etcdctl member list -w table
+------------------+---------+-------+--------------------------+--------------------------+------------+
|        ID        | STATUS  | NAME  |        PEER ADDRS        |       CLIENT ADDRS       | IS LEARNER |
+------------------+---------+-------+----------------------------+------------------------+------------+
| 670b863301943618 | started | node1 | http://192.168.0.10:2380 | http://192.168.0.10:2379 |      false |
| 7825d7b04510b842 | started | node3 | http://192.168.0.11:2380 | http://192.168.0.11:2379 |      false |
| c8245114d55ec576 | started | node2 | http://192.168.0.12:2380 | http://192.168.0.12:2379 |      false |
+------------------+---------+-------+----------------------------+------------------------+------------+
```

* `ID` : 해당 노드의 고유한 식별자로 ETCD 리더 노드를 선출하는 Raft 알고리즘에 이용됩니다.
* `STATUS` : 해당 노드가 부팅되어 클러스터의 리더 선출에 성공적으로 참여 하였는지를 나타내는 값으로 `started` 혹은 `unstarted` 값을 가질 수 있습니다. 아직 시작된 적이 없는 ETCD3 노드의 경우 `unstarted` 값을 가집니다.
* `NAME` : 해당 노드의 고유한 이름으로 ETCD3 서버 프로세스 시작 시 `--name` 인자로 지정한 값입니다.
* `PEER ADDRS` : 해당 노드의 Advertise 된 Peer 통신을 위한 URL의 목록입니다.
* `CLIENT ADDRS` : 해당 노드의 Advertise 된 Client 통신을 위한 URL의 목록입니다.
* `IS LEARNER` : 해당 멤버가 ETCD 클러스터로부터 Snapshot 및 WAL 복제 상태를 유지하지만 리더 선출 Quorum 에는 참여하지 않는 [Learner](https://etcd.io/docs/v3.3/learning/learner/) 노드인지를 나타냅니다.

### **클러스터 엔드포인트 조회**

`etcdctl endpoint status` 로 클러스터의 모든 멤버 노드들의 접속 URL, 데이터베이스 크기, Leader 여부 및 Raft 정보를 확인할 수 있습니다.

```bash
$ etcdctl endpoint status -w table
+--------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|         ENDPOINT         |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+--------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.0.10:2379 | 670b863301943618 |  3.5.21 |  168 kB |      true |      false |         6 |        520 |                520 |        |
| http://192.168.0.11:2379 | c8245114d55ec576 |  3.5.21 |  168 kB |     false |      false |         6 |        520 |                520 |        |
| http://192.168.0.12:2379 | 7825d7b04510b842 |  3.5.21 |  168 kB |     false |      false |         6 |        520 |                520 |        |
+--------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
```

* `ENDPOINT` : 해당 노드의 Advertise 된 Client 통신을 위한 URL의 목록입니다.
* `ID` : `ENDPOINT` 와 동일합니다.
* `VERSION` : 해당 노드에서 구동중인 ETCD3 서버의 버전을 나타냅니다.
* `DB SIZE` : 디스크에 저장된 ETCD3 데이터베이스의 크기를 나타냅니다.
* `IS LEADER` : 해당 노드가 이 클러스터의 Raft Leader 인지 여부를 나타냅니다.
* `IS LEARNER` : `IS LEADER` 와 동일합니다.
* `RAFT TERM` : Raft 알고리즘에 따른 현재 임기 (Term). 새로운 Leader 선출이 이루어질 때마다 값이 1씩 늘어납니다.
* `RAFT INDEX` : 해당 노드에 저장된 쓰기 작업의 Log Entry 위치를 나타냅니다. Leader 선출 시 참조하며 Raft Index가 가장 높은 (즉 가장 최신 상태를 유지하고 있는) 노드가 Leader 선출 시 우선권을 갖습니다.
* `RAFT APPLIED INDEX` : 해당 노드의 로컬 환경 Key-Value Store에 적용되어 (Applied) 읽기 가능한 상태의 Log Entry 위치를 나타냅니다. 노드의 CPU 및 디스크 환경에 따라 Raft Applied Index가 Raft Index 보다 작은 값을 갖는 (즉 데이터 쓰기 작업이 지연되는) 상황이 발생할 수 있으며 이 경우 클라이언트 설정에 따라 Data Consistency가 유지되지 않을 수 있습니다.
  * `etcdctl get` 플래그 `--consistency` 값에 따라 동작이 달라집니다. `--consistency=s` (Serializable, default) 인 경우 과거 시점의 데이터를 불러옵니다. `--consistency=l` (Linearizable) 인 경우 질의하는 서버가 최신 Raft Index를 따라잡을 때까지 대기한 후 최신 시점의 데이터를 불러옵니다.
* `ERRORS` : 해당 노드의 Endpoint에서 감지된 문제를 메세지 형태로 표현합니다.

***

## **데이터 조회**

ETCD3 클러스터에 저장된 데이터를 직접 조회합니다.

### **Prefix로 조회**

`etcdctl get` 명령어 인자로 `--prefix` 옵션을 지정해 선행하는 특정 문자열과 매칭되는 Key들을 조회할 수 있습니다.

```bash
$ etcdctl get --prefix "/opensql/opensql/members" -w simple
/opensql/opensql/members/pg-1
{"conn_url":"postgres://192.168.131.12:5432/postgres","api_url":"http://192.168.131.12:8008/patroni","state":"running","role":"replica","version":"4.0.5","proxy_url":"postgres://192.168.131.15:6432/postgres","xlog_location":223510016,"replication_state":"streaming","timeline":3}
/opensql/opensql/members/pg-2
{"conn_url":"postgres://192.168.131.13:5432/postgres","api_url":"http://192.168.131.13:8008/patroni","state":"running","role":"primary","version":"4.0.5","proxy_url":"postgres://192.168.131.15:6432/postgres","xlog_location":223510016,"timeline":3}
/opensql/opensql/members/pg-3
{"conn_url":"postgres://192.168.131.14:5432/postgres","api_url":"http://192.168.131.14:8008/patroni","state":"running","role":"replica","version":"4.0.5","proxy_url":"postgres://192.168.131.15:6432/postgres","xlog_location":223510016,"replication_state":"streaming","timeline":3}
```

### **Range로 조회**

`etcdctl get` 명령어 인자로 특정 Key 값 `key` 와 다른 Key `range_end` 를 지정하여 Key 인덱스 공간의 두 지점 사이, 정확히는 `[key, range_end)` 에 해당하는 Key의 목록을 조회할 수 있습니다.

* ETCD3에 저장되는 모든 Key들은 Byte의 배열로 치환되어 Index 공간에 저장되며 대소를 비교하여 색인됩니다.
  * `aa` < `ab`
  * `a\xff` < `b`
* `range_end` 와 일치하는 Key는 포함되지 않습니다. (Exclusive)

```bash
$ etcdctl get "/opensql/opensql/members/pg-1" "/opensql/opensql/members/pg-3"
/opensql/opensql/members/pg-1
{"conn_url":"postgres://192.168.131.12:5432/postgres","api_url":"http://192.168.131.12:8008/patroni","state":"running","role":"replica","version":"4.0.5","proxy_url":"postgres://192.168.131.15:6432/postgres","xlog_location":223510016,"replication_state":"streaming","timeline":3}
/opensql/opensql/members/pg-2
{"conn_url":"postgres://192.168.131.13:5432/postgres","api_url":"http://192.168.131.13:8008/patroni","state":"running","role":"primary","version":"4.0.5","proxy_url":"postgres://192.168.131.15:6432/postgres","xlog_location":223510016,"timeline":3}

$ etcdctl get "/opensql/opensql/failover" "/opensql/opensql/historz"
/opensql/opensql/failover
{}
/opensql/opensql/history
[[1,223438192,"no recovery target specified","2025-04-18T14:27:03.269756+09:00","pg-1"],[2,223438824,"no recovery target specified","2025-04-21T15:13:37.632010+09:00","pg-2"]]
```

***

## **데이터베이스 유지 보수**

ETCD3는 동시성 있는 클라이언트 접근을 제어하며 데이터 일관성을 유지하기 위해 Revision 정보를 기반으로 한 MVCC (Multi-Version Concurrency Control) 를 이용합니다. 클러스터가 오랜 기간 유지되며 Patroni Switchover / Failover 등의 동작이 많이 일어난 경우 실제 Patroni에서 ETCD3 클러스터에 저장하는 데이터 사이즈가 작음에도 DB 사이즈가 계속해서 증가하는 문제가 발생할 수 있습니다.

### **정리할 대상 Revision 지정**

`etcdctl compact` 명령어로 특정 Revision을 지정해 그 이전 시점의 Revision을 더 이상 참조되지 않는 상태로 정의합니다. 해당 동작은 클러스터 단위의 작업이므로 별도의 endpoint를 지정하지 않고 실행할 수 있습니다.

```bash
## Endpoint Status를 확인해 각 노드에서 유지하고 있는 가장 최신 Revision 정보를 가져온다.
$ etcdctl endpoint status -w json | jq | grep 'revision'
        "revision": 447871,
        "revision": 447871,
        "revision": 447871,

## 해당 Revision 이전 시점의 Revision들을 더 이상 참조되지 않는 상태로 지정한다.
$ rev=447871
$ etcdctl compact $rev
compacted revision 447871
```

### **데이터 조각모음**

`etcdctl defrag` 명령어로 참조되지 않는 Revision을 DB File에서 삭제해 디스크 공간을 확보합니다. 별도 `--endpoints` 옵션이 없으면 로컬 노드의 디스크 공간만을 확보합니다. 클러스터의 모든 Endpoint URL을 `--endpoints` 옵션으로 지정하면 각 호스트들의 디스크 공간을 모두 확보합니다.

```bash
$ etcdctl defrag --endpoints "http://192.168.0.10:2379,http://192.168.0.11:2379,http://192.168.0.12:2379"
Finished defragmenting etcd member[http://192.168.0.10:2379]
Finished defragmenting etcd member[http://192.168.0.11:2379]
Finished defragmenting etcd member[http://192.168.0.12:2379]

$ etcdctl endpoint status --endpoints "..."
http://192.168.0.10:2379, 670b863301943618, 3.5.21, 25 kB, true, false, 8, 448000, 448000, 
http://192.168.0.11:2379, c8245114d55ec576, 3.5.21, 25 kB, false, false, 8, 448000, 448000, 
http://192.168.0.12:2379, 7825d7b04510b842, 3.5.21, 25 kB, false, false, 8, 448000, 448000,
```

### **쓰기 성능 테스트**

`etcdctl check perf` 명령어로 1분 동안 클러스터의 쓰기 전체 처리량 (Throughput)을 테스트 할 수 있습니다.

```bash
$ etcdctl check perf
 60 / 60 Booooooooooooooooooooooooooooooooooooooooooooooooooooooom! 100.00% 1m0s
PASS: Throughput is 150 writes/s
PASS: Slowest request took 0.291186s
PASS: Stddev is 0.029467s
PASS
```

`--load` 옵션으로 요청하는 클라이언트 수 및 초당 요청 횟수를 다르게 지정할 수 있습니다.

* `s` : 50 Clients, 초당 쓰기 작업 최대 150 건
* `m` : 200 Clients, 초당 쓰기 작업 최대 1000 건
* `l` : 500 Clients, 초당 쓰기 작업 최대 8000 건
* `xl` : 1000 Clients, 초당 쓰기 작업 최대 15000 건

출력되는 결과에는 PASS / FAIL Criteria가 존재합니다.

* 생성된 요청의 90% 이상 Throughput이 나와야 합니다.
* 모든 요청은 500 ms 안에 처리되어야 합니다.
* 요청의 처리에 걸린 시간의 표준 편차 (stddev) 가 100 ms 이하여야 합니다.

```bash
$ etcdctl check perf
 60 / 60 Booooooooooooooooooooooooooooooooooooooooooooooooooooooom! 100.00% 1m0s
PASS: Throughput is 150 writes/s
Slowest request took too long: 0.535645s
PASS: Stddev is 0.079037s
FAIL

$ etcdctl check perf --load="xl"
 60 / 60 Booooooooooooooooooooooooooooooooooooooooooooooooooooooom! 100.00% 1m0s
FAIL: Throughput too low: 3668 writes/s
Slowest request took too long: 0.645609s
Stddev too high: 0.105516s
FAIL
```

성능 테스트로 가해진 부하가 많은 경우 DB Revision History로 인해 ETCD 데이터베이스 사이즈가 크게 증가할 수 있으므로 `compact` 및 `defrag` 작업을 수행할 것을 권장합니다.

***

## **복구**

ETCD3 는 클러스터 노드의 접속 URL, 클러스터 토큰, Listen URL 등 자신을 포함한 클러스터의 모든 구성을 데이터베이스 스냅샷과 같이 관리합니다. 이미 구성되어 있는 ETCD3 클러스터의 노드의 환경설정을 변경하여 Key-Value 데이터만 보존한 채로 재시작하는 경우에는 일반적으로 동작하지 않습니다.

서비스 중단으로 인해 발생한 장애로 Scale-In이 요구되거나, 새로운 노드를 추가해 Scale-Out을 진행하거나, 호스트의 IPv4 주소가 변경되어 클러스터를 재설정해야 하는 등 이미 구성된 ETCD3 클러스터의 환경 구성을 변경하여 재시작하고자 하는 경우, 명령줄 도구 `etcdctl` 을 이용해 복구를 진행해야 합니다.

### **스냅샷 확인**

복구를 위해서는 가져오고자 하는 Key-Value 데이터가 포함된 ETCD3 노드의 스냅샷 (Snapshot) 이 필요합니다. ETCD3의 스냅샷은 관계형 데이터베이스의 데이터 파일에 대응되며, 특정 시점에 ETCD3 클러스터에 저장된 Key-Value 데이터뿐만 아니라 클러스터의 구성 정보 및 상태 (Raft State) 를 같이 저장합니다. 파일 시스템에 저장된 ETCD3의 `db` 파일을 가져오거나, 구동 중인 ETCD3 클러스터로부터 생성할 수 있습니다.

#### **파일시스템에서 확인**

ETCD3 데이터 경로 `ETCD_DATA_DIR` 하부 경로 `member/snap/db` 에 위치합니다.

```bash
$ ls -l $ETCD_DATA_DIR/member/snap/
total 168
-rw-------. 1 opensql opensql 16805888 Apr 18 14:29 db

$ cp $ETCD_DATA_DIR/member/snap/db ./mysnapshot.db
```

#### **구동중인 ETCD3로부터 생성**

명령줄 도구 `etcdctl` 의 `snapshot save` 명령어를 이용해 ETCD3 서버로부터 현재 시점의 Snapshot을 생성할 수 있습니다.

* 여러 노드로 구성된 클러스터가 동작 중이어도 `ENDPOINT` 인자로는 하나의 ETCD3 서버 URL만 주어져야 합니다.

```bash
$ ETCDCTL_API=3 etcdctl --endpoints=${ENDPOINT} snapshot save mysnapshot.db

{"level":"info","ts":"2025-04-21T12:18:30.406283+0900","caller":"snapshot/v3_snapshot.go:65","msg":"created temporary db file","path":"mysnapshot.db.part"}
{"level":"info","ts":"2025-04-21T12:18:30.407142+0900","logger":"client","caller":"v3@v3.5.21/maintenance.go:212","msg":"opened snapshot stream; downloading"}
{"level":"info","ts":"2025-04-21T12:18:30.407162+0900","caller":"snapshot/v3_snapshot.go:73","msg":"fetching snapshot","endpoint":"192.168.131.12:2379"}
{"level":"info","ts":"2025-04-21T12:18:30.432538+0900","logger":"client","caller":"v3@v3.5.21/maintenance.go:220","msg":"completed snapshot read; closing"}
{"level":"info","ts":"2025-04-21T12:18:30.480983+0900","caller":"snapshot/v3_snapshot.go:88","msg":"fetched snapshot","endpoint":"192.168.131.12:2379","size":"168 kB","took":"now"}
{"level":"info","ts":"2025-04-21T12:18:30.481039+0900","caller":"snapshot/v3_snapshot.go:97","msg":"saved","path":"mysnapshot.db"}
Snapshot saved at mysnapshot.db
```

### **스냅샷으로부터 데이터 복구**

명령줄 도구 `etcdctl` 의 `snapshot restore` 명령어를 이용해 Snapshot으로부터 ETCD3 클러스터 데이터를 생성할 수 있습니다.

* ETCD3 클러스터를 초기 구성할 때와 마찬가지로 새롭게 구성할 클러스터의 초기 설정 중 Database Snapshot에 포함되는 인자들이 명령줄 인자로 모두 주어져야 합니다.
  * `--name` : 복구하여 새로 생성할 ETCD3 서버의 노드 이름을 지정합니다.
  * `--initial-cluster` : 클러스터 내 모든 ETCD3 서버의 노드 이름 및 Peer 통신을 위한 Endpoint URL 을 지정합니다.
  * `--initial-cluster-token` : 클러스터에 참여하기 위한 Initialize Token 을 지정합니다.
  * `--initial-advertise-peer-urls` : 클러스터의 다른 노드에 알릴 이 노드의 Peer 통신을 위한 Endpoint URL 을 지정합니다.
* `--skip-hash-check` 옵션은 복구될 원본 스냅샷의 데이터 무결성을 검증하는 과정을 생략하기 위한 옵션입니다.
  * `snapshot save` 명령어로 구동중인 ETCD3 서버에서 생성한 스냅샷의 경우 데이터 무결성이 유지되므로 해당 옵션 없이도 정상적으로 복구할 수 있습니다.
  * 파일 시스템에서 복사해 온 ETCD3 데이터 `db` 파일의 경우 실행 시점의 클러스터 메타 정보를 포함하므로 해당 옵션 없이는 정상적으로 복구할 수 없습니다. `--skip-hash-check` 옵션을 부여해 데이터 무결성 검증을 생략합니다.

```bash
$ ETCDCTL_API=3 etcdctl snapshot restore ./mysnapshot.db \
  --name node3 \
  --initial-cluster node1=http://192.168.0.8:2380,node2=http://192.168.0.9:2380,node3=http://192.168.0.10:2380 \
  --initial-cluster-token new-etcd-cluster \
  --initial-advertise-peer-urls http://192.168.0.10:2380 \
  --skip-hash-check \
  # ...

Deprecated: Use `etcdutl snapshot restore` instead.

snapshot/v3_snapshot.go:248	restoring snapshot	{"path": "member/snap/db", "wal-dir": "node3.etcd/member/wal", "data-dir": "node3.etcd", "snap-dir": "node3.etcd/member/snap", "stack": "go.etcd.io/..." }
membership/store.go:141	Trimming membership information from the backend...
membership/cluster.go:421	added member	{"cluster-id": "154dfe96307df6f0", "local-member-id": "0", "added-peer-id": "3dfe6fc7fff49d22", "added-peer-peer-urls": ["http://192.168.0.8:2380"]}
membership/cluster.go:421	added member	{"cluster-id": "154dfe96307df6f0", "local-member-id": "0", "added-peer-id": "7f846315e3b9872d", "added-peer-peer-urls": ["http://192.168.0.9:2380"]}
membership/cluster.go:421	added member	{"cluster-id": "154dfe96307df6f0", "local-member-id": "0", "added-peer-id": "c0ea9022befd3eaa", "added-peer-peer-urls": ["http://192.168.0.10:2380"]}
snapshot/v3_snapshot.go:269	restored snapshot	{"path": "member/snap/db", "wal-dir": "node3.etcd/member/wal", "data-dir": "node3.etcd", "snap-dir": "node3.etcd/member/snap"}
```

* 데이터가 성공적으로 복구 된 경우 `${ETCD_NAME}.etcd` 이름의 디렉토리 안에 새로운 클러스터가 구성됩니다.

```bash
$ ls -l
total 0
drwx------. 3 root root  20 Mar 17 14:48 node1.etcd

$ ls -l node1.etcd/
drwx------. 2 root root 246 Mar 17 14:41 snap
drwx------. 2 root root 257 Mar 17 14:41 wal
```

* 복구 된 데이터 디렉토리를 기반으로 ETCD3 서비스를 재시작합니다. 데이터 복구 시 사용한 인자와 서비스 재시작 시 사용하는 인자가 일치해야 합니다.
  * 생성된 `${ETCD_NAME}.etcd` 디렉토리는 기존 ETCD3 데이터 경로 밑의 `member/` 서브디렉토리와 대응됩니다.

```bash
$ rm -rf $ETCD_DATA_DIR/member

$ cp -r node1.etcd $ETCD_DATA_DIR/member

## Service 정의에 참조된 etcd.env 파일 내용 확인
$ vi $OPENSQL_HOME/etc/etcd/etcd.env
ETCD_NAME=node1

ETCD_INITIAL_CLUSTER=node1=http://192.168.0.8:2380,node2=http://192.168.0.9:2380,node3=http://192.168.0.10:2380
ETCD_INITIAL_CLUSTER_TOKEN=new-etcd-cluster
ETCD_INITIAL_CLUSTER_STATE=new
  --initial-cluster-token new-etcd-cluster \
  --initial-advertise-peer-urls http://192.168.0.8:2380 \

$ systemctl restart etcd.service
```

{% hint style="info" %}
**참고**

<https://github.com/etcd-io/etcd/blob/v3.4.19/Documentation/op-guide/recovery.md>
{% endhint %}

###


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tibero.com/tmaxopensql/administration/etcd.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
