> For the complete documentation index, see [llms.txt](https://docs.tibero.com/tibero-manuals/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/tibero-manuals/7.2.6.manuals/administrator-guide/tibero-cluster-manager.md).

# Tibero Cluster Manager

Tibero Cluster Manager의 기본 개념과 환경설정 및 실행 방법을 설명합니다.

## 개요

**Tibero Cluster Manager**(이하 CM)는 클러스터의 가용성을 높이고 관리의 편의를 지원합니다. 또한, Tibero Active Cluster 서비스를 위한 인스턴스 간 멤버십 관리를 지원합니다. CM에서는 클러스터의 각종 구성 요소들을 리소스라는 개념으로 관리하도록 되어 있습니다.

다음은 현재 CM에서 관리 가능한 클러스터 리소스입니다.

* File
* Network
* Cluster
* Service
* DB(Database)
* AS(Active Storage)
* VIP
* Group
* Agent

CM은 등록된 리소스들에 대한 모니터링을 수행하며, 상태 변화에 따른 필요 동작들을 수행합니다. 설정을 통해 같은 클러스터에 속하게 된 CM들 간에는 지정된 네트워크와 공유 디스크를 통해 주기적으로 자신이 살아 있음을 알리는 Heartbeat를 서로 주고받으며 클러스터의 멤버십 구성을 파악하게 됩니다.

클러스터 구성 CM 중 하나의 CM이 마스터의 역할을 맡아 비정상적인 상황이 발생하는 경우 클러스터 멤버십을 자동으로 변경하여, 해당 클러스터 상의 서비스가 중단되지 않도록 합니다. 마스터에 문제가 생긴 경우 클러스터에 속한 다른 노드가 마스터 역할을 넘겨받습니다.

## 환경 변수 및 초기화 파라미터

### 환경 변수

환경 변수 CM\_HOME과 CM\_SID를 설정해야 합니다. 다음은 그 예제입니다. 이 외에 RDBMS를 실행하기 위해 필요한 기본 환경 변수는 “[관리의 기본](/tibero-manuals/7.2.6.manuals/administrator-guide/basic-database-administration.md)”을 참고하여 설정합니다.

<table><thead><tr><th width="154">환경 변수</th><th>설명</th></tr></thead><tbody><tr><td>$CM_HOME</td><td>CM이 설치된 경로를 지정<br><br>예) <code>export CM_HOME=/home/tibero7</code></td></tr><tr><td>$CM_SID</td><td><ul><li>노드를 식별할 수 있는 ID를 지정</li><li>각 노드는 서로 다른 값을 가져야 함</li></ul><p><br>예) <code>export CM_SID=cm0</code></p></td></tr></tbody></table>

### 초기화 파라미터

CM용 TIP에는 다음과 같은 파라미터들을 설정할 수 있습니다. 필수 항목은 사용자가 TIP에 명시적으로 값을 지정해야 하며, 선택 항목은 사용자가 지정하지 않을 수 있고 이 경우 기본값으로 입력됩니다.

<table><thead><tr><th>초기화 파라미터</th><th width="62">필수 여부</th><th>설명</th></tr></thead><tbody><tr><td>CM_NAME</td><td>필수</td><td><ul><li>클러스터를 생성할 때의 node identifier로 쓸 이름</li><li>서로 다른 노드의 CM은 다른 값을 가져야 함</li></ul></td></tr><tr><td>CM_UI_PORT</td><td>필수</td><td><ul><li>cmrctl 명령어 수행 시 CM으로 접속하는 용도로 사용할 네트워크 포트 번호</li><li>이 포트는 노드 간에 열려 있어야 함</li></ul></td></tr><tr><td>CM_RESOURCE_FILE</td><td>필수</td><td><ul><li>CM 리소스 파일의 경로를 지정</li><li>CM 리소스 파일은 다음과 같은 상황에서 사용됨</li><li>동작 중인 CM이 등록된 리소스의 내용을 저장해 두기 위해 사용하는 파일 – 리소스를 추가, 변경하거나 삭제할 때 리소스 파일에 자동으로 동기화</li></ul></td></tr><tr><td>CM_RESOURCE_FILE_BACKUP</td><td>선택</td><td>CM 리소스 파일의 백업 경로를 지정</td></tr><tr><td>CM_RESOURCE_FILE_BACKUP_INTERVAL</td><td>선택</td><td>CM_RESOURCE_FILE_BACKUP 경로에 CM 리소스 파일의 백업을 수행할 시간 간격을 나타냄 (단위: 분)</td></tr><tr><td>LOG_LVL_CM</td><td>선택</td><td><ul><li>CM이 로그를 남기는 수준을 지정</li><li>값이 높을수록 CM이 더 많은 로그를 저장하며, 1~6 사이의 정수값을 가질 수 있음(기본값: 3)</li></ul></td></tr><tr><td>CM_LOG_DEST</td><td>선택</td><td><ul><li>CM이 로그를 남길 디렉터리를 지정</li><li>이 값은 반드시 절대 경로여야 함 (기본값: $CM_HOME/instance/$CM_SID/log/)</li></ul></td></tr><tr><td>CM_GUARD_LOG_DEST</td><td>선택</td><td><p>CM Guard가 로그 파일을 저장할 장소로 이 값은 반드시 로컬 디스크의 절대 경로여야 함</p><p>(기본값: $CM_HOME/instance/$CM_SID/log/cm_guard/)</p><ul><li>Windows는 Guard가 뜨지 않음</li></ul></td></tr><tr><td>CM_LOG_FILE_SIZE</td><td>선택</td><td><ul><li>CM 로그 파일의 최대 크기(용량)를 지정</li><li>로그가 계속 생성되어 파일의 크기가 값을 넘어설 경우 현재의 로그 파일이 닫히고, 새로운 파일이 생성되어 그 파일에 로그가 저장됨</li><li>값은 100KB~1GB 사이의 정수값을 가질 수 있음(단위: Byte, 기본값: 10MB)</li></ul></td></tr><tr><td>CM_LOG_TOTAL_SIZE_LIMIT</td><td>선택</td><td><ul><li>CM_LOG_DEST에서 지정한 디렉터리에 생성되는 로그 파일들의 크기 총합의 최댓값을 지정</li><li>로그 파일들의 크기 합이 값을 넘어가기 전까지는, 가장 오래된 파일을 삭제함으로써 파일 용량이 줄어든 후 새로운 로그 파일을 생성함으로써 증가하는 것을 막음</li><li>이 값은 100KB~10GB 사이의 정수값을 가질 수 있음 (단위: byte, 기본값: 300MB)</li></ul></td></tr><tr><td>CM_TIME_UNIT</td><td>선택</td><td>CM을 컨트롤할 때 사용되는 단위 시간의 길이를 지정 (단위: 0.1초, 기본값: 10)</td></tr><tr><td>CM_HEARTBEAT_EXPIRE</td><td>선택</td><td><ul><li>Heartbeat expire란 다른 노드의 CM에 문제가 생겼다는 것을 CM이 알아차리는 데 필요한 표준 시간 값을 의미</li><li>즉, 현재 노드의 CM에서 Heartbeat expire 시간이 지나도록 통신이 되지 않는 CM이 있으면, 현재 노드의 CM에 문제가 생겼다고 인식하게 됨 (단위: 초(second), 기본값: 300)</li></ul></td></tr><tr><td>CM_NET_EXPIRE_MARGIN</td><td>선택</td><td><ul><li>CM을 컨트롤하기 위한 네트워크의 Heartbeat expire 시간</li><li>이 값은 5보다 크거나 같아야 함<br>(단위: 초(second), 기본값: 5)</li></ul></td></tr><tr><td>CM_WATCHDOG_EXPIRE</td><td>선택</td><td><ul><li>RDBMS와 CM 사이에 watchdog 기능이 활성화되어 있을 경우 만료 기간(expiration period)을 지정</li><li>만약 CM이 이 값으로 지정한 시간 동안 동작하지 않으면, RDBMS가 자동으로 종료</li><li>CM_HEARTBEAT_EXPIRE보다 작은 값을 사용해야 함<br>(단위: 초(second), 기본값: 290)</li></ul></td></tr><tr><td>CM_FENCE</td><td>선택</td><td><ul><li>CM fence 데몬을 실행시킬지를 결정</li><li>CM이 I/O 수행을 CM_WATCHDOG_EXPIRE에 지정된 시간보다 오래할 경우, 다른 CM들이 이 CM의 노드를 클러스터에서 제외시키기 때문에 이 CM의 노드는 OS를 재부팅해야 함(그 노드의 RDBMS가 I/O 하는 것을 막기 위해)</li><li>CM fence 데몬은 이러한 일을 수행하며, 재부팅 권한이 필요하므로 이 값을 Y로 지정하려면 CM이 ROOT 권한으로 실행되어야 함 (기본값: N)</li></ul></td></tr><tr><td>CM_ENABLE_FAST_NET_ERROR_DETECTION</td><td>선택</td><td>다른 CM들과 연결된 네트워크의 장애를 감지함으로써 다른 CM의 상태 변화를 빨리 알아차릴 수 있도록 하는 기능을 활성화시킬지를 결정 (기본값: Y)</td></tr></tbody></table>

## **CM** 실행

CM 데몬 실행 이후의 작업들은 cmrctl 명령어를 사용하여 수행합니다. CM은 다음의 방법으로 실행합니다.

```
tbcm [option] <argument>
```

* **\[option]**

<table><thead><tr><th width="168">항목</th><th>설명</th></tr></thead><tbody><tr><td>-b</td><td>CM 데몬 실행</td></tr><tr><td>-d</td><td>CM 데몬 종료</td></tr><tr><td>-i &#x3C;<em>file path</em>></td><td>지정 경로의 text 파일에서 리소스 정보 import</td></tr><tr><td>-e &#x3C;<em>file path</em>></td><td>현재 CM에 추가된 리소스 정보를 지정 경로에 text 파일로 export</td></tr><tr><td>-x &#x3C;<em>file path</em>></td><td>현재 CM에 추가된 리소스 정보를 지정 경로에 파일로 export</td></tr><tr><td>-X</td><td>현재 CM에 추가된 리소스 정보를 CM_RESOURCE_FILE 지정 경로에 export</td></tr><tr><td>-s</td><td><ul><li>CM 상태 조회</li><li>초기화 파라미터 등록 내용 표시</li></ul></td></tr><tr><td>-v</td><td>CM 버전 조회</td></tr><tr><td>-h</td><td>tbcm 명령어 도움말 조회</td></tr><tr><td>-g &#x3C;level></td><td>지정 레벨로 로그 레벨 변경(5 ~ 7)</td></tr></tbody></table>

## **CM** 명령어

CM 명령어인 cmrctl, crfconf에 대해서 설명합니다.

### **cmrctl** 명령어

cmrctl은 New CM에서 리소스들을 관리 및 제어하기 위해 사용하는 명령어 set입니다.

기본적인 cmrctl 명령어 용법은 다음과 같습니다.

```
cmrctl <action> <resource_type> [--<attr_key> <attr_val>|...]
```

<table><thead><tr><th width="191">항목</th><th>설명</th></tr></thead><tbody><tr><td><em>action</em></td><td>add, del, show, start, stop, act, deact, modify, relocate, set</td></tr><tr><td><em>resource_type</em></td><td>network, cluster, service, db, as, vip, file, group, agent, param</td></tr></tbody></table>

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

어떤 action, resource type의 조합은 사용이 불가능할 수도 있습니다. (예: add, file)
{% endhint %}

#### **cmrctl 명령어를 통한 CM 원격 제어**

같은 클러스터를 구성 중인 CM에 대해서 cmrctl 명령에 추가 attribute를 명시함으로써 원격 제어가 가능합니다. 원격 제어를 할 CM 노드의 이름과 해당 노드가 속한 클러스터의 이름을 알고 있어야 하며, 다음과 같은 attribute를 cmrctl 명령에 추가합니다.

```
--remote <node_name>@<cluster_name>
```

다음의 예제 구문처럼 해당 attribute는 cmrctl add와 cmrctl del 명령에는 사용할 수 없습니다.

```
# cls1 클러스터에 속한 cm2 노드의 리소스 조회
$ cmrctl show --remote cm2@cls1

# cls1 클러스터에 속한 cm1 노드의 tibero1 db down
$ cmrctl stop db --name tibero1 --remote cm1@cls1

# 원격으로 resource add 시 error 발생
$ cmrctl add db --name tac1 ... --remote cm1@cls1
[ERROR] Cannot add (or delete) resource remotely
```

지정한 클러스터가 down 상태이거나 지정한 노드가 down 상태일 경우 또는 잘못된 클러스터/노드 이름을 입력했을 경우에는 에러 메시지를 출력합니다.

#### **cmrctl add**

cmrctl add는 다음의 명령어로 구성됩니다.

<table><thead><tr><th width="293">명령어</th><th>설명</th></tr></thead><tbody><tr><td>cmrctl add network</td><td>네트워크 리소스를 추가하기 위한 명령어</td></tr><tr><td>cmrctl add cluster</td><td>클러스터 리소스를 추가하기 위한 명령어</td></tr><tr><td>cmrctl add service</td><td>서비스 리소스를 추가하기 위한 명령어</td></tr><tr><td>cmrctl add db</td><td>Tibero 인스턴스를 추가하는 명령어</td></tr><tr><td>cmrctl add as</td><td>AS(Active Storage) 인스턴스를 추가하는 명령어</td></tr><tr><td>cmrctl add vip</td><td>VIP를 등록하기 위한 명령어</td></tr><tr><td>cmrctl add group</td><td>그룹을 추가하기 위한 명령어</td></tr><tr><td>cmrctl add agent</td><td>에이전트를 추가하기 위한 명령어</td></tr></tbody></table>

#### **cmrctl add network**

네트워크 리소스를 추가하기 위한 명령어입니다. 네트워크가 public/private 용도에 따라서 필요한 attribute가 나뉩니다. 네트워크 리소스는 interconnect로 사용할 IP, PORT 조합이나 VIP 등록을 위해 필요한 public 네트워크 인터페이스 등록에 사용하는 자원입니다. 등록된 이후에 지정된 네트워크 인터페이스를 감시하여 자동으로 상태를 갱신합니다.

```
cmrctl add network --name <network_name> --nettype <private|public>
--ipaddr <network_ipaddr/netmask_addr> --portno <port_no> --ifname <interface_name>
```

<table><thead><tr><th width="142">Key</th><th width="165">Value Type</th><th>설명</th></tr></thead><tbody><tr><td>name</td><td>string</td><td>네트워크 리소스 이름 (unique, mandatory)</td></tr><tr><td>nettype</td><td>string</td><td>네트워크 리소스의 type<br>– private : interconnect를 의미(기본값)<br>– public : VIP 용으로 사용</td></tr><tr><td>ipaddr</td><td>string</td><td><ul><li>interconnect로 사용할 IP 주소</li><li>이 포트는 노드 간에 열려 있어야 함(only for nettype 'private'. mandatory)</li></ul></td></tr><tr><td>portno</td><td>integer</td><td>CM 간의 interconnect로 사용할 포트 번호(only for nettype 'private', mandatory)</td></tr><tr><td>ifname</td><td>string</td><td>public 용도로 사용할 interface name(VIP 등록용)<br>(only for nettype 'public', mandatory)</td></tr></tbody></table>

{% hint style="info" %}
참고\
private type 네트워크 리소스는 DB의 interconnect 장애 감지에 사용되므로, DB에서 사용되는 interconnect의 interface에 할당된 ip 주소로 등록해야 한다.
{% endhint %}

#### **cmrctl add cluster**

클러스터 리소스를 추가하기 위한 명령어입니다. 클러스터 리소스는 환경의 개념으로 노드 간 연결에 사용하는 interconnect, 노드 간 공유하는 스토리지, VIP를 사용하는 경우에 필요한 public network interface로 구성됩니다.

```
cmrctl add cluster --name <cluster_name> --incnet <network_resource_name>
--pubnet <public_network_resource_name> --cfile <file_path>
```

<table><thead><tr><th width="103">Key</th><th width="134">Value Type</th><th>설명</th></tr></thead><tbody><tr><td>name</td><td>string</td><td>클러스터 리소스 이름 (unique, mandatory)</td></tr><tr><td>incnet</td><td>string</td><td>interconnect 용도로 사용할 네트워크 리소스 이름(mandatory)</td></tr><tr><td>pubnet</td><td>string</td><td><ul><li>public 용도로 사용할 네트워크 리소스 이름</li><li>VIP를 사용하는 경우 등록</li></ul></td></tr><tr><td>cfile</td><td>file path</td><td><ul><li>클러스터 파일 경로입니다. 콤마(,)로 구분하여 여러 개 등록할 수 있음 (mandatory)</li><li>cfile attribute의 경우 가장 앞에 '+'를 붙이면 TAS용 경로(diskstring)로 인식<br><br>– 예제 1) 올바른 경로 사용 방법<br><code>--cfile "/dev/sda,/dev/sdb,/dev/sdc"</code><br><code>--cfile "/mnt/file1,/mnt/file2,/mnt/file3"</code><br><code>--cfile "+/dev/sda,/dev/sdb,/dev/sdc"</code><br>일반 경로와 TAS 경로를 혼용할 수 없음<br><br>– 예제 2) 잘못된 사용 방법<br>“+/dev/sdb”라는 경로는 없으므로 인식하지 못함<br><code>--cfile "+/dev/sda,/ +/dev/sdb"</code><br><code>--cfile "/dev/sda,/ +/dev/sdb"</code><br>TAS용 경로를 사용하는 경우 AS_DISKSTRING으로 지정한 디스크와 나중에 추가될 디스크를 모두 포함해야 함. 따라서 디스크 추가가 예상되는 경우 wildcard 사용을 권장.<br><br>– 예제 3) 나중에 추가될 /dev/sdd를 고려하는 경우<br><code>--cfile "+/dev/sd*"</code><br><code>--cfile "+/dev/sda,/dev/sdb,/dev/sdc,/dev/sdd"</code><br><br>– 예제 4) 나중에 추가될 sdd를 고려하지 못한 경우. sdd가 추가되어 TAS rebalance에 의해 cfile의 위치가 변경되면 CM이 cfile을 찾지 못하게 될 수 있음. 이 경우 cluster 재구성을 통한 cfile 재등록이 필요.</li></ul><p>(나중에 추가될 sdd를 고려하지 못한 경우)</p><p><code>--cfile "+/dev/sda,/dev/sdb,/dev/sdc"</code></p><p>(클러스터 재구성을 통한 cfile 재등록)</p><p><code>--cfile "+/dev/sda,/dev/sdb,/dev/sdc,/dev/sdd"</code></p><p>TAS를 사용하는 환경에서 TAS가 관리하는 디스크를 '+' prefix 없이 cfile로 등록하게 되면 raw device로 인식하게 되어 TAS 디스크를 덮어쓸 수 있으므로 주의가 필요함<br><br>– 예제 5) TAS가 사용 중인 /dev/sda를 덮어쓰게 되는 경우<br><code>--cfile "/dev/sda"</code><br>스토리지 서버를 사용할 경우에는 다음과 같이 지정합니다.<br><br>– 예제 6)<br><code>--cfile "-"</code><br><br>[참고]<br>1. cfile은 TAS용 경로가 아닌 raw device나 파일로 지정할 경우를 우선 1개로 지정하는 것을 권장(권고사항).<br>2. 파일 리소스의 경우 사용자가 수동으로 추가하는 것이 아니라, 클러스터 리소스의 --cfile로 등록된 내용으로 자동 생성됨. TAS diskstring을 등록한 경우 +0, +1, +2와 같은 형태로 리소스가 생성됨.</p></td></tr></tbody></table>

#### **cmrctl add service**

서비스 리소스를 추가하기 위한 명령어입니다. 서비스는 클러스터라는 환경 위에서 실제 어떤 서비스를 제공하는 인스턴스의 집합을 관리하기 위한 개념입니다.

```
cmrctl add service --name <service_name> --type <DB|AS> --mode <AC|HA>
--cname <cluster_resource_name>
```

<table><thead><tr><th width="121">Key</th><th width="133">Value Type</th><th>설명</th></tr></thead><tbody><tr><td>name</td><td>string</td><td><ul><li>서비스 리소스 이름 (unique, mandatory)</li><li>서비스 리소스 이름은 해당 서비스와 매핑되는 DB의 DB_NAME 파라미터와 같아야 함(TAS는 TIP 파일에 DB_NAME을 안 적어도 되지만, 적는다면 서비스의 이름과 같아야 함).</li></ul></td></tr><tr><td>type</td><td>string</td><td><p>서비스 타입</p><p>– DB : Tibero 인스턴스가 동작하는 서비스(기본값)</p><p>– AS : TAS 인스턴스가 동작하는 서비스</p></td></tr><tr><td>mode</td><td>string</td><td><p>서비스 인스턴스 클러스터링 모드</p><p>– AC : 한 서비스에 대한 인스턴스가 여러 노드에서 동시에 실행되어 동작 가능한 모드 (기본값)</p><p>– HA : 한 서비스에 대한 인스턴스가 하나만 동작 가능한 모드</p></td></tr><tr><td>cname</td><td>string</td><td>해당 서비스 리소스가 속할 클러스터 리소스 이름(mandatory)</td></tr></tbody></table>

AS 서비스의 경우에는 한 클러스터당 하나만 등록 가능합니다. 서비스 리소스는 특정 클러스터를 지정하여 추가하도록 되어 있는데, 한 노드에 추가하면 해당 노드가 속한 클러스터의 모든 노드에 자동으로 공유됩니다.

#### **cmrctl add db**

Tibero 인스턴스를 추가하는 명령어입니다. DB type의 서비스에만 추가 가능합니다.

```
cmrctl add db --name <db_resource_name> --svcname <service_name>
--dbhome <directory_path> --envfile <file_path> --retry_cnt <retry_cnt>
--retry_interval <retry_interval>
```

<table><thead><tr><th width="138">Key</th><th width="191">Value Type</th><th>설명</th></tr></thead><tbody><tr><td>name</td><td>string</td><td><ul><li>DB 리소스 이름</li><li>DB 리소스의 name은 해당 DB 인스턴스의 TB_SID와 동일해야 함 (unique, mandatory)</li></ul></td></tr><tr><td>svcname</td><td>string</td><td>DB 리소스가 속한 서비스 리소스 이름 (mandatory)</td></tr><tr><td>dbhome</td><td>string(directory path)</td><td>기존의 TB_HOME 개념으로 DB 바이너리가 위치한 경로 (mandatory)</td></tr><tr><td>envfile</td><td>string(file path)</td><td><p>DB 바이너리를 실행하기 위한 환경설정용 파일(recommended)</p><p>[참고]</p><ul><li>envfile은 DB 리소스별로 지정하는 것을 권장</li><li>envfile에는 RDBMS를 부팅하고 종료하기 위해 필요한 환경변수들을 export하는 내용이 들어감</li></ul></td></tr><tr><td>retry_cnt</td><td>integer</td><td>최대 retry 시도 횟수 (기본값: 3)</td></tr><tr><td>retry_interval</td><td>integer</td><td>retry 시도 간의 간격 (단위: 초, 기본값: 1)</td></tr></tbody></table>

다음은 envfile을 입력하지 않았을 때 default로 수행되는 내용입니다. 이 외의 환경변수들은 CM이 부팅할 때 터미널이 가지고 있던 환경변수가 그대로 적용됩니다. LD\_LIBRARY\_PATH는 Linux 또는 SunOS를 사용할 경우이고, AIX를 사용할 경우 LIBPATH, HP-UX는 SHLIB\_PATH를 export합니다. 환경변수 설정에 대한 자세한 내용은 "[Tibero 설치 안내서](/tibero-manuals/7.2.6.manuals/installation-guide.md)"를 참고합니다.

```
export TB_SID=name                  # db 리소스의 name
export TB_HOME=dbhome               # db 리소스의 dbhome
export PATH=$TB_HOME/bin:$TB_HOME/client/bin:/usr/bin:$PATH
export LD_LIBRARY_PATH=$TB_HOME/lib:$TB_HOME/client/lib:$LD_LIBRARY_PATH
```

#### **cmrctl add as**

AS(Active Storage) 인스턴스를 추가하는 명령어입니다. AS type의 서비스에만 추가 가능합니다.

```
cmrctl add as --name <as_resource_name> --svcname <service_name>
--dbhome <directory_path> --envfile <file_path> --retry_cnt <retry_cnt>
--retry_interval <retry_interval>
```

<table><thead><tr><th width="145">Key</th><th width="194">Value Type</th><th>설명</th></tr></thead><tbody><tr><td>name</td><td>string</td><td>AS 리소스 이름 (unique, mandatory)</td></tr><tr><td>svcname</td><td>string</td><td>AS 리소스가 속할 서비스 리소스 이름(mandatory)</td></tr><tr><td>dbhome</td><td>string(directory path)</td><td>기존의 TB_HOME 개념으로 AS 바이너리가 위치한 경로 (mandatory)</td></tr><tr><td>envfile</td><td>string(file path)</td><td>AS 바이너리를 실행하기 위한 환경설정용 파일 (recommended)</td></tr><tr><td>retry_cnt</td><td>integer</td><td>최대 retry 시도 횟수(기본값: 3)</td></tr><tr><td>retry_interval</td><td>integer</td><td>retry 시도 간격(단위: 초, 기본값: 0(retry 기능 사용하지 않음))</td></tr></tbody></table>

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

AS 리소스의 name은 해당 AS 인스턴스의 TB\_SID와 동일해야 합니다. envfile에 관한 설명은 "[cmrctl add db](#cmrctl-add-db)"를 참고합니다.
{% endhint %}

#### **cmrctl add vip**

VIP를 등록하기 위해서는 tbcm이 ROOT 권한으로 실행되어 있어야 하며, svcname으로 지정한 서비스에 pubnet attribute가 등록되어 있어야 합니다. 환경변수 PATH에 /sbin 경로가 잡혀 있지 않으면 VIP alias에 실패하므로 확인해야 합니다. 또한 vip 기능 사용을 위해 net-tools를 반드시 설치해야 합니다.

#### **VIP failover/failback**

클러스터의 특정 노드에서 장애가 발생하면 사용 중인 VIP를 정상적으로 작동하는 노드 중 한 노드에 VIP를 옮겨 설정합니다(failover). 이를 통해서 Tibero는 장애가 발생한 노드의 VIP로도 계속해서 서비스를 할 수 있습니다. 장애가 발생했던 노드가 복구되면 다시 원래 소유했던 노드로 VIP를 옮겨 설정합니다(failback).

```
cmrctl add vip --name <vip_name> --node <CM_SID> --svcname <service_name>
--ipaddr <vip_ipaddr/netmask_addr> --bcast <bcast_addr>
```

<table><thead><tr><th width="147">Key</th><th width="237">Value Type</th><th>설명</th></tr></thead><tbody><tr><td>name</td><td>string</td><td>VIP 리소스 이름. (unique, mandatory)</td></tr><tr><td>node</td><td>string</td><td>VIP를 원래 소유했던 CM_SID(optional, 기본값: 해당 명령어를 수행한 노드의 CM_SID)</td></tr><tr><td>svcname</td><td>string</td><td>VIP를 사용할 서비스 이름(mandatory)</td></tr><tr><td>ipaddr</td><td>string(IP address/Netmask)</td><td><p>VIP IP address/Netmask로 조합된 주소</p><ul><li>IP address (mandatory)</li><li>Netmask (optional, 기본값: public interface의 netmask)</li></ul></td></tr><tr><td>bcast</td><td>Broadcast</td><td>VIP broadcast 주소 (optional)</td></tr><tr><td>retry_cnt</td><td>integer</td><td>최대 retry 시도 횟수 (기본값: 3)</td></tr><tr><td>retry_interval</td><td>integer</td><td>retry 시도 간격<br>(단위: 초, 기본값: 0(retry 기능 사용하지 않음))</td></tr></tbody></table>

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

VIP로 접속할 때 사용해야 할 포트는 DB 인스턴스에서 LISTENER\_VIP\_PORT로 설정이 가능합니다. 설정한 포트는 VIP failback 과정에서 세션을 정리해 주기 위해 잠시 막힙니다. LISTENER\_VIP\_PORT와 LISTENER\_PORT를 다르게 설정한다면 VIP failback 과정 중에도 LISTENER\_PORT로의 접속은 가능합니다.
{% endhint %}

#### **cmrctl add group**

그룹 리소스를 추가하기 위한 명령어입니다. 그룹은 클러스터라는 환경 위에서 제공하는 에이전트의 집합을 관리하기 위한 개념입니다.

```
cmrctl add group --name <group_name> --grptype <group_type> --failover <true|false>
--cname <cluster_resource_name>
```

<table><thead><tr><th width="157">Key</th><th width="149">Value Type</th><th>설명</th></tr></thead><tbody><tr><td>name</td><td>string</td><td>그룹 리소스 이름(unique, mandatory)</td></tr><tr><td>grptype</td><td>string</td><td><ul><li>그룹의 타입(optional)</li><li>그룹의 종류를 나타내기 위한 용도(기본값: "")</li></ul></td></tr><tr><td>failover</td><td>boolean</td><td><p>그룹에 속한 에이전트의 failover 기능 사용 여부</p><ul><li>true : 에이전트가 종료되었을 때 failover 기능 사용 여부(기본값, optimal)</li><li>false : 에이전트는 failover되지 않음</li></ul></td></tr><tr><td>cname</td><td>string</td><td>해당 서비스 리소스가 속할 클러스터 리소스 이름(mandatory)</td></tr></tbody></table>

그룹 리소스는 특정 클러스터를 지정하여 추가하도록 되어 있는데, 한 노드에 추가하면 해당 노드가 속한 클러스터의 모든 노드에 자동으로 공유됩니다.

#### **cmrctl add agent**

에이전트를 추가하는 명령어입니다.

```
cmrctl add agent --name <agent_resource_name> --grpname <group_name>
--script <script_path> --retry_cnt <retry_cnt>
--pubnet <public_network_resource_name>
```

<table><thead><tr><th width="106">Key</th><th width="150">Value Type</th><th>설명</th></tr></thead><tbody><tr><td>name</td><td>string</td><td><ul><li>에이전트 리소스 이름</li><li>에이전트 리소스의 name은 관리하고자 하는 에이전트의 이름과 동일해야 함</li><li>등록된 이름으로 pid를 찾음 (unique, mandatory)</li></ul></td></tr><tr><td>grpname</td><td>string</td><td>에이전트 리소스가 속할 그룹 리소스 이름 (mandatory)</td></tr><tr><td>script</td><td>string(file path)</td><td><ul><li>에이전트 관리를 위해 수행할 스크립트의 절대 경로(mandatory)</li><li>에이전트별로 별도의 스크립트를 구성 및 등록하면 cm에서 주기적으로 스크립트를 수행</li></ul></td></tr><tr><td>retry_cnt</td><td>integer</td><td>최대 retry 시도 횟수 (기본값: 3)</td></tr><tr><td>pubnet</td><td>string</td><td>public 네트워크는 클러스터의 failover 조건이 아니므로 failover 조건에 네트워크를 추가하기 위한 용도(optional)</td></tr></tbody></table>

#### **cmrctl del (delete)**

특정 리소스를 삭제하기 위한 명령어이며, DOWN 또는 DEACT 상태의 리소스만 삭제 가능합니다.

```
cmrctl del <resource_type> --name <resource_name>
```

#### **cmrctl show**

CM에 등록된 리소스의 정보를 확인하기 위한 명령어입니다.

다음의 3가지 방법으로 사용이 가능합니다.

**방법 1)**

현재 CM 데몬에 등록된 리소스의 목록을 출력합니다.

```
cmrctl show
```

현재 CM 데몬의 클러스터에 등록된 모든 노드의 리소스 목록을 출력합니다.

```
cmrctl show all
```

**방법 2)**

```
cmrctl show <resource_type>
```

현재 CM 데몬에 등록된 리소스들 중 \<resource\_type>의 리소스 목록을 출력합니다.

**방법 3)**

```
cmrctl show <resource_type> --name <resource_name>
```

지정한 특정 리소스의 상세한 정보를 출력합니다.

**방법 4)**

값을 변경한 CM 파라미터를 출력합니다.

```
cmrctl show param
```

CM 파라미터를 모두 출력합니다.

```
cmrctl show param all
```

특정 파라미터 정보를 출력합니다.

```
cmrctl show param [PARAMETER]
```

#### **cmrctl start**

특정 리소스를 시작하기 위한 명령어입니다. 서비스 리소스를 start하는 경우 해당 서비스에 속한 모든 인스턴스를 기동시킵니다.

서비스나 인스턴스 리소스의 경우 --option을 통해 bootmode를 지정해줄 수 있습니다.

```
cmrctl start <resource_type> --name <resource_name> [--option <options>]
```

#### **cmrctl stop**

특정 리소스를 중지하기 위한 명령어입니다. 서비스 리소스를 stop하는 경우 해당 서비스에 속한 모든 인스턴스를 중지시킵니다. 또한, auto-restart 기능이 동작 중이라면 중지됩니다.

서비스나 인스턴스 리소스의 경우 --option을 통해 shutdown mode를 지정해줄 수 있습니다.

auto-restart 모드가 동작 중에 서비스의 인스턴스가 중지된 경우 해당 상황을 인지한 후에 중지된 인스턴스를 재시작시켜주는 기능입니다.

```
cmrctl stop <resource_type> --name <resource_name> [--option <options>]
```

#### **cmrctl act**

다음의 이유로 인해 deactivate된 리소스를 다시 activate시켜주기 위한 명령어입니다.

* DB 또는 AS 리소스를 추가할 때 입력한 retry\_cnt(기본값: 3) 이상 start를 수행했는데도 실패한 경우
* 사용자가 cmrctl deact 명령어를 명시적으로 사용하여 비활성화시킨 경우

서비스 리소스를 act하는 경우에는 해당 서비스 리소스의 인스턴스들에 대한 auto-restart 기능을 동작시키겠다는 의미로 사용됩니다.

```
cmrctl act <resource_type> --name <resource_name>
```

#### **cmrctl deact**

특정 리소스를 deactivate시켜주기 위한 명령어이며, deactivate된 리소스는 auto-restart 대상에서 제외됩니다. 서비스 리소스를 deact하는 경우에는 해당 서비스 리소스의 인스턴스들에 대한 auto-restart 기능을 중지시키겠다는 의미로 사용됩니다.

```
cmrctl deact <resource_type> --name <resource_name>
```

#### **cmrctl modify**

인스턴스 리소스의 retry\_cnt, retry\_interval을 변경시켜주기 위한 명령어입니다.

```
cmrctl modify <resource_type> --name <resource_name>
```

#### **cmrctl relocate**

CM 멀티노드 환경에서 vip의 소유권 이전/변경하기 위한 명령어입니다.

```
cmrctl relocate vip --name <vip_name> --nid <target_nid>
```

target\_nid는 vip 소유권을 가질 노드로서 cmrctl show cluster --name \[cluster\_name] 명령어를 통해 노드별 nid 및 현재 vip를 소유하는 nid를 확인할 수 있습니다.

#### **cmrctl set**

CM 파라미터 값을 변경하기 위한 명령어입니다.

```
cmrctl set param [PARAMETER=VALUE]
```

동적으로 변경 가능한 파라미터를 cm 기동 중에 변경하고 싶을 때 사용합니다.

### **crfconf** 명령어

cmrctl 명령어의 경우 CM이 온라인 상태일 때 CM에 접속하여 사용자가 리소스를 관리할 수 있는 명령어라면, crfconf는 CM이 오프라인 상태일 때 CM TIP에 지정된 경로에 있는 CM 리소스 파일에 접근하여 해당 파일을 관리할 수 있도록 하는 유틸리티입니다. CM 리소스 파일의 경우 바이너리 파일이기 때문에 사용자가 임의로 파일을 수정할 수 없습니다. 따라서, 사용자가 CM을 부팅하기 전에 CM 리소스 파일에 있는 리소스 정보를 변경하려면 **crfconf**를 사용하여 원하는 작업을 수행할 수 있습니다. 이때 VIP 등과 같은 글로벌 리소스의 변경을 시도하는 경우에는 마스터가 관리하기 때문에 마스터로 기동할 CM의 CM 리소스 파일을 변경해야 정상적으로 적용됩니다.

crfconf의 사용법은 cmrctl과 동일하며, 사용 가능한 action이 add, del, show의 3가지로 제한된다는 점만 다릅니다.

```
crfconf <action> <resource_type> [--<attr_key> <attr_val>|...]
```

CM이 리소스 파일에 접근할 수 있는 CM 동작 상황에서는 crfconf를 수행할 때 다음과 같은 에러를 출력하며 실패로 처리됩니다.

```
$ crfconf show
[ERROR] CM is online. use 'cmrctl' command crfconf failed!
```

## Cluster Resource의 ROOT 모드

CM이 VIP 등과 같은 글로벌 리소스를 관리할 때 클러스터의 구성원이 모두 ROOT 권한이어야 하는 일들이 발생합니다. 따라서 클러스터 리소스에는 ROOT 모드라는 것이 존재하는데, 어떤 클러스터에 포함된 모든 CM들이 ROOT 권한으로 실행되었을 때 그 클러스터는 ROOT 모드가 됩니다. ROOT 모드의 클러스터는 ROOT 모드를 유지하기 위해 ROOT 권한이 없는 CM이 접속하는 것을 막습니다.

다음은 클러스터가 ROOT 모드가 되는 두 가지 예입니다.

* **클러스터에 처음 접속한 CM이 ROOT 권한으로 띄워진 경우**\
  이 경우 해당 클러스터는 시작부터 ROOT 모드가 되므로, 이 이후로 클러스터에 접속하려는 CM들은 모두 ROOT 권한으로 실행되어야만 접속이 가능합니다.<br>
* **클러스터 내의 ROOT 권한으로 실행되지 않은 노드들이 모두 down된 경우**\
  5개의 노드로 구성된 클러스터를 생각해 봅니다. 1\~2번 노드는 ROOT 권한 없이 실행된 CM이고, 3\~5번 노드는 ROOT 권한으로 실행된 CM이라면 이 순간 해당 클러스터는 ROOT 모드가 아닙니다. 이때 1번과 2번 노드를 다운시키면, 클러스터에 접속해 있는 CM은 3개가 되고, 3개 모두 ROOT 권한을 가진 CM이므로 클러스터가 ROOT 모드가 됩니다. 이후로는 클러스터가 ROOT 모드이기 때문에 1번과 2번 노드가 다시 클러스터에 접속하기 위해서는 ROOT 모드로 CM을 실행시켜야만 합니다.

ROOT 모드 클러스터에는 ROOT 권한이 없는 CM이 접속할 수 없으므로, ROOT 모드 클러스터를 ROOT 모드가 아닌 클러스터로 만들려면 모든 노드에서 클러스터를 down시킨 후 ROOT 권한이 없는 CM이 처음 클러스터에 접속하도록 해야 합니다. 단, ROOT 모드가 아닌 클러스터에는 ROOT 권한 유무에 상관없이 CM이 접속할 수 있지만, ROOT 권한을 가진 CM이라 해도 VIP 사용이 불가능하다는 점을 주의할 필요가 있습니다.

어떤 CM이 ROOT 권한을 가지고 실행되었는지와 클러스터가 ROOT 모드인지는 다음의 방법으로 확인할 수 있습니다.

```
cmrctl show cluster --name 'cluster name'
```

다음은 2-node-cluster에서 두 노드 모두 ROOT 권한이 있는 CM으로 접속한 상황입니다. Status의 UP 옆에 (ROOT)라는 표시는 cluster가 ROOT 모드임을 의미하며, NODE LIST에 Mst 아래 R은 각 노드 CM의 ROOT 권한 소유를 의미합니다.

```
cmrctl show cluster --name cls1

Cluster Resource Info
=====================================================================

Cluster name   : cls1
Status         : UP          (ROOT)
Master node    : (1) cm0
Last NID       : 2
Local node     : (2) cm1
Storage type   : Active Storage
As Diskstring  : /data/*
No. of cls files : 3
        (1) +0
        (2) +1
        (3) +2

=====================================================================

|                               NODE LIST                            |
|--------------------------------------------------------------------|
| NID  Name   IP/PORT         Status Schd Mst  FHB  NHB              |
| ---  ------ ---------------- ------ ---- ---- ---- ----            |
|  1   cm0    123.1.1.1/29000  UP     Y   R    M    30   35          |
|  2   cm1    124.1.1.1/29100  UP     Y   R    [ LOCAL ]             |
=====================================================================
```

다음은 두 노드 모두 ROOT 권한이 없는 CM으로 클러스터에 접속한 상황입니다. 앞에서와 달리 Status에 (ROOT)가 없고, NODE LIST에도 Mst에 R을 가진 노드가 없습니다.

```
cmrctl show cluster --name cls1

Cluster Resource Info
=====================================================================

Cluster name   : cls1
Status         : UP
Master node    : (1) cm0
Last NID       : 2
Local node     : (2) cm1
Storage type   : Active Storage
As Diskstring  : /data/*
No. of cls files : 3
        (1) +0
        (2) +1
        (3) +2

=====================================================================

|                               NODE LIST                            |
|--------------------------------------------------------------------|
| NID  Name   IP/PORT         Status Schd Mst  FHB  NHB              |
| ---  ------ ---------------- ------ ---- ---- ---- ----            |
|  1   cm0    123.1.1.1/29000  UP     Y   M    30   35               |
|  2   cm1    124.1.1.1/29100  UP     Y   [ LOCAL ]                  |
=====================================================================
```

다음은 한 노드가 ROOT 권한이 없는 CM으로 클러스터에 접속하고, 다른 노드는 ROOT 권한을 가진 CM으로 접속한 상황입니다. 노드 2번만 Mst에 R이 있고, 클러스터가 ROOT 모드가 아니므로 Cluster Resource Info의 Status에 (ROOT)가 없습니다.

```
cmrctl show cluster --name cls1

Cluster Resource Info
=====================================================================

Cluster name   : cls1
Status         : UP
Master node    : (1) cm0
Last NID       : 2
Local node     : (2) cm1
Storage type   : Active Storage
As Diskstring  : /data/*


No. of cls files : 3
        (1) +0
        (2) +1
        (3) +2

=====================================================================

|                               NODE LIST                            |
|--------------------------------------------------------------------|
| NID  Name   IP/PORT         Status Schd Mst  FHB  NHB              |
| ---  ------ ---------------- ------ ---- ---- ---- ----            |
|  1   cm0    123.1.1.1/29000  UP     Y   M    30   35               |
|  2   cm1    124.1.1.1/29100  UP     Y   R    [ LOCAL ]             |
=====================================================================

```

마지막으로 바로 위의 상황에서 루트 권한이 없는 1번 노드의 클러스터를 stop시킨 후 다시 cluster start를 하려는 상황입니다. 1번 노드에서 클러스터가 stop됨으로 인해 클러스터에 ROOT 권한 노드만 남게 되고, 이에 따라 클러스터가 ROOT 모드가 됨을 확인할 수 있습니다. 또한 클러스터가 ROOT 모드이므로, ROOT 권한이 없는 1번 노드 CM은 클러스터에 재접속할 수 없게 됩니다.

**1번 노드**

```
cmrctl stop cluster --name cls1
```

```
cmrctl start cluster --name cls1

Failed to start the resource 'cls1'
  [ERROR] To join this cluster(cls1), you must be root
```

\
**2번 노드**

```
cmrctl show cluster --name cls1

Cluster Resource Info
=====================================================================

Cluster name   : cls1
Status         : UP          (ROOT)
Master node    : (1) cm1
Last NID       : 2
Local node     : (2) cm1
Storage type   : Active Storage
As Diskstring  : /data/*
No. of cls files : 3
        (1) +0
        (2) +1
        (3) +2

=====================================================================

|                               NODE LIST                            |
|--------------------------------------------------------------------|
| NID  Name   IP/PORT         Status Schd Mst  FHB  NHB              |
| ---  ------ ---------------- ------ ---- ---- ---- ----            |
|  1   cm0    123.1.1.1/29000  DOWN   N   0    0    0                |
|  2   cm1    124.1.1.1/29100  UP     Y   R    M    [ LOCAL ]        |
=====================================================================
```

## **TAC** 구성

TAC의 구성을 위해 Linux 환경에서 참고할 수 있는 예제를 설명합니다.

1번 노드에서의 TB\_SID와 CM\_SID는 각각 ac1와 cm1, 2번 노드에서의 TB\_SID와 CM\_SID는 각각 ac2와 cm2로 정하였습니다. 먼저 CM TIP 파일을 설정해야 합니다. 위의 초기화 파라미터에 보면 필수 항목이 3개이므로 그 3개는 반드시 설정해야 합니다.

1. 본 예제에서는 1번 노드를 위한 CM TIP 파일을 1번 노드의 $TB\_HOME/config 아래에 cm1.tip으로, 2번 노드를 위한 CM TIP 파일을 2번 노드의 $TB\_HOME/config 아래에 cm2.tip으로 저장하였으며, 다음과 같이 TIP 파일을 작성하였습니다(config 폴더에 저장해야 합니다).

<\<cm1.tip>>

```
CM_NAME=cm1
CM_UI_PORT=8635
CM_RESOURCE_FILE=/home/tibero7/cm1_res.crf
```

<\<cm2.tip>>

```
CM_NAME=cm2
CM_UI_PORT=8655
CM_RESOURCE_FILE=/home/tibero7/cm2_res.crf
```

2. 다음으로 TAC용 TIP 파일을 설정해야 합니다.

본 예제에서는 1번 노드를 위한 TAC TIP 파일을 1번 노드의 $TB\_HOME/config 아래에 ac1.tip으로, 2번 노드를 위한 TAC TIP 파일을 2번 노드의 $TB\_HOME/config 아래에 ac2.tip으로 저장합니다. “Tibero Active Cluster”를 보면 각 파라미터들의 의미를 알 수 있습니다(본 예제에서는 TB\_HOME이 /home/tibero7입니다).

<\<ac1.tip>>

```
DB_NAME=ac        # DB_NAME은 ac1과 ac2가 같은 값을 가진다.
LISTENER_PORT=21000
CONTROL_FILES="/home/tibero7/database/ac/c1.ctl"

MAX_SESSION_COUNT=20
TOTAL_SHM_SIZE=512M
MEMORY_TARGET=1G
THREAD=0
UNDO_TABLESPACE=UNDO0

CLUSTER_DATABASE=Y
LOCAL_CLUSTER_ADDR=123.1.1.1
LOCAL_CLUSTER_PORT=21100
CM_PORT=8635 # cm1의 CM_UI_PORT
```

<\<ac2.tip>>

```
DB_NAME=ac        # DB_NAME은 ac1과 ac2가 같은 값을 가진다.
LISTENER_PORT=21010
CONTROL_FILES="/home/tibero7/database/ac/c1.ctl"


MAX_SESSION_COUNT=20
TOTAL_SHM_SIZE=512M
MEMORY_TARGET=1G
THREAD=1
UNDO_TABLESPACE=UNDO01


CLUSTER_DATABASE=Y
LOCAL_CLUSTER_ADDR=124.1.1.1
LOCAL_CLUSTER_PORT=21110
CM_PORT=8655 # cm2의 CM_UI_PORT

```

3. 1번 노드부터 구성을 하면 먼저 CM을 실행시켜야 하는데, 이를 위해서는 CM\_SID가 앞서 작성한 TIP 파일의 파일 이름과 같아야 합니다(따라서 본 예제에서는 CM\_SID가 cm1이어야 합니다).

CM\_SID를 설정하기 위해 아래 내용을 터미널에서 실행합니다. TB\_SID도 함께 설정합니다(나중에 데이터베이스를 만들 때 필요합니다).

```
export CM_SID=cm1
export TB_SID=ac1
```

4. 이렇게 CM\_SID 설정을 완료하면, 아래의 명령어를 이용해 CM을 실행합니다.

```
tbcm -b
```

성공적으로 부팅되었다면, 다음과 같이 출력됩니다.

```
CM Guard daemon started up.
import resources from '/home/tibero7/cm1_res.crf'...

Tibero 7

TmaxData Corporation Copyright (c) 2008-. All rights reserved.


Tibero cluster manager started up.
Local node name is (cm1:8635).
```

이 과정을 거치고 나면 CM\_RESOURCE\_FILE에 설정해 놓은 디렉터리에 cm1\_res.crf라는 리소스 바이너리 파일이 생성됩니다. 이 파일에 앞으로 등록할 리소스에 대한 정보가 저장됩니다.

5. 완료되면 CM의 부팅 상태를 확인하기 위해 다음과 같이 명령어를 실행합니다.

```
cmrctl show
```

다음과 같이 나온다면 정상적인 상황입니다(아직 아무런 리소스도 등록하지 않았기 때문에 CLUSTER, TYPE, NAME, STATUS, DETAIL이 모두 빈칸입니다).

```
Resource List of Node cm1

==============================================================

  CLUSTER    TYPE       NAME        STATUS      DETAIL
----------  --------  ----------  ----------  --------------------

==============================================================
```

6. 먼저 아래의 명령어처럼 네트워크 리소스를 등록합니다.

```
cmrctl add network --name net1 --ipaddr 123.1.1.1 --portno 29000
```

성공적으로 리소스가 등록되면 다음과 같이 출력됩니다.

```
Resource add success! (network, net1)
```

7. 다시 한 번 cmrctl show를 이용하여 리소스 상태를 확인하면 다음과 같이 출력됩니다.

```
Resource List of Node cm1

==============================================================

  CLUSTER    TYPE       NAME        STATUS        DETAIL
----------  --------  ----------  -----------  --------------------

   COMMON   network     net1        UP (private) 123.1.1.1/29000

==============================================================
```

8. 다음으로 아래의 명령어와 같은 방법으로 클러스터를 등록합니다. 이때, cfile이 저장될 폴더는 미리 만들어 놓아야 합니다. 또한, cfile 경로는 공유 디스크에 있도록 지정해야 합니다.

```
cmrctl add cluster --name cls1 --incnet net1 --cfile /'shared disk 경로'/cls1_cfile
```

성공적으로 클러스터 리소스가 등록되면 다음과 같이 출력됩니다.

```
Resource add success! (cluster, cls1)
```

9. cmrctl show를 이용하여 리소스 상태를 확인하면 다음과 같이 출력됩니다.

```
Resource List of Node cm1

==============================================================

  CLUSTER    TYPE       NAME        STATUS        DETAIL
----------  --------  ----------  -----------  -------------------------

   COMMON   network     net1        UP (private) 123.1.1.1/29000
   COMMON   cluster     cls1        DOWN inc: net1, pub: N/A

==============================================================
```

10. 등록된 클러스터 아래에 TAC 서비스 리소스를 등록해야 하는데, 그에 앞서 클러스터 cls1을 활성화시켜야 합니다.

```
cmrctl start cluster --name cls1
```

성공적으로 클러스터가 시작되면 root 권한 여부에 따라 다음과 같이 출력됩니다. (이때 실패한다면 cfile이 저장될 디렉터리를 미리 안 만들어 놓았을 가능성이 높습니다.)

```
MESSAGE SENDING SUCCESS 또는 No root permission! vip is not available.
```

11. cmrctl show를 이용하여 리소스 상태를 확인하면 다음과 같이 출력됩니다.

```
Resource List of Node cm1
==============================================================

  CLUSTER    TYPE       NAME        STATUS        DETAIL
----------  --------  ----------  -----------  -------------------------
   COMMON   network     net1        UP (private) 123.1.1.1/29000
   COMMON   cluster     cls1        UP inc: net1, pub: N/A
    cls1    file        cls1:0      UP '/shared disk 경로'/cls1_cfile
==============================================================
```

12. 다음과 같은 명령어를 이용해 서비스 리소스를 등록합니다(이때, 서비스의 이름은 나중에 만들 데이터베이스의 이름과 같아야 합니다).

```
cmrctl add service --name ac --cname cls1
```

성공적으로 등록하면 다음과 같이 출력됩니다.

```
Resource add success! (service, ac)
```

13. cmrctl show를 이용하여 리소스 상태를 확인하면 다음과 같이 출력됩니다.

```
Resource List of Node cm1
==============================================================

  CLUSTER    TYPE       NAME        STATUS        DETAIL
----------  --------  ----------  -----------  -------------------------
   COMMON   network     net1        UP (private) 123.1.1.1/29000
   COMMON   cluster     cls1        UP inc: net1, pub: N/A
    cls1    file        cls1:0      UP '/shared disk 경로'/cls1_cfile
    cls1    service     ac          DOWN Database, Active Cluster
                                           (auto-restart: OFF)
==============================================================

```

14. 마지막으로 DB 리소스를 등록합니다.

여기서 --name의 값은 Active Cluster에서 해당 노드가 사용할 TB\_SID(본 예제에서는 ac1을 사용)와 같아야 합니다. ac1을 위한 환경변수 설정을 담은 envfile은 /home/tibero7/ 아래에 envfile\_ac1으로 저장하였습니다.

```
cmrctl add db --name ac1 --svcname ac --dbhome /home/tibero7
--envfile /home/tibero7/envfile_ac1
```

성공적으로 등록하면 다음과 같이 출력됩니다.

```
Resource add success! (db, ac1)
```

15. cmrctl show를 이용하여 리소스 상태를 확인하면 다음과 같이 출력됩니다.

```
Resource List of Node cm1
==============================================================

  CLUSTER    TYPE       NAME        STATUS        DETAIL
----------  --------  ----------  -----------  -------------------------
   COMMON   network     net1        UP (private) 123.1.1.1/29000
   COMMON   cluster     cls1        UP inc: net1, pub: N/A
    cls1    file        cls1:0      UP '/shared disk 경로'/cls1_cfile
    cls1    service     ac          DOWN Database, Active Cluster
                                           (auto-restart: OFF)
    cls1    db          ac1         DOWN ac, /home/tibero7
==============================================================
```

16. 이제 실제로 운용할 데이터베이스를 만들어야 합니다. “TAC를 위한 데이터베이스 생성” 과정의 2번\~6번까지의 과정을 실행합니다. 과정을 수행하는 데 다음의 두 가지 유의사항을 지켜야 합니다.

– tbsql로 접속하기 위해 tbdsn.tbr을 설정할 때 다음과 같은 내용들을 넣어주어야 합니다.

```
ac1=(
        (INSTANCE=(HOST=123.1.1.1)
                 (PORT=21000)
                 (DB_NAME=ac)
        )
)
```

– 접속 후 “TAC를 위한 데이터베이스 생성”에서 데이터베이스를 만들 때 CREATE DATABASE "ac" (앞서 입력한 서비스 리소스의 이름)로 해야 합니다. 데이터베이스 생성을 모두 마치고 나면, cmrctl show의 결과에서 다음과 같이 STATUS가 모두 UP으로 바뀌어 있습니다.

```
Resource List of Node cm1
==============================================================

CLUSTER   TYPE      NAME    STATUS                         DETAIL
--------  --------  ------- ------------------------------ ------------------------------
COMMON    network   net1    UP (private)                   123.1.1.1/29000
COMMON    cluster   cls1    UP inc: net1, pub: N/A
cls1      file      cls1:0  UP                             '/shared disk 경로'/cls1_cfile
cls1      service   ac      UP Database, Active Cluster    (auto-restart: OFF)
cls1      db        ac1     UP ac                          /home/tibero7

==============================================================
```

17. 이로써 첫 노드 구성이 끝났습니다. 이제 다음 노드를 구성해야 합니다. 먼저 2번 노드의 tbdsn.tbr 설정을 마친 후 다음 명령어를 차례대로 입력합니다. 이때 유의할 점은 클러스터를 추가할 때 cfile의 경로가 앞서 1번 노드에서 설정한 cfile의 경로와 같아야 합니다.

```
export CM_SID=cm2
export TB_SID=ac2

tbcm -b
cmrctl add network --name net1 --ipaddr 124.1.1.1 --portno 29100
cmrctl add cluster --name cls1 --incnet net1 --cfile '/shared disk 경로'/cls1_cfile
cmrctl start cluster --name cls1
```

18. cmrctl show를 해 보면 다음과 같이 서비스가 이미 등록되어 있는 것을 확인할 수 있습니다. 이는 cfile에 있는 내용을 cm1에서 직접 읽어 왔기 때문입니다.

```
Resource List of Node cm2
==============================================================

CLUSTER   TYPE      NAME    STATUS                         DETAIL
--------  --------  ------- ------------------------------ ------------------------------
COMMON    network   net1    UP (private)                   124.1.1.1/29100
COMMON    cluster   cls1    UP inc: net1, pub: N/A
cls1      file      cls1:0  UP                             '/shared disk 경로'/cls1_cfile
cls1      service   ac      UP Database, Active Cluster  (auto-restart: OFF)

==============================================================
```

19. 마지막으로 ac2가 사용할 envfile을 저장한 후 다음의 명령어들을 입력하면 2노드 TAC 구성과 실행이 완료됩니다.

```
cmrctl add db --name ac2 --svcname ac --dbhome /home/tibero7 \
--envfile /home/tibero7/envfile_ac2

cmrctl start service --name ac
```

## TAS-TAC 구성

본 절에서는 먼저 TAS를 구성하는 과정에 대해서 설명합니다.

다음은 TAS-TAC(Tibero Active Storage - Tibero Active Cluster)의 구성을 위해 Linux 환경에서 참고할 수 있는 예제입니다.

* 1번 노드에서 TAS를 위한 TB\_SID를 as1, TAC를 위한 TB\_SID를 ac1, CM을 위한 CM\_SID를 cm1으로 합니다. TB\_SID를 따서 예제 내용을 as1.tip은 1번 노드의 $TB\_HOME/config/as1.tip에 저장합니다.
* 2번 노드에서 TAS를 위한 TB\_SID를 as2, TAC를 위한 TB\_SID를 ac2, CM을 위한 CM\_SID를 cm2로 합니다. TB\_SID를 따서 예제 내용을 as2.tip은 2번 노드의 $TB\_HOME/config/as2.tip에 저장합니다. TAS는 DB\_NAME을 지정하지 않고, TAC는 DB\_NAME을 ac로 합니다.

전체적인 흐름은 TAS를 구성하고 “TAC 구성”에 설명된 정보를 수정해서 수행합니다.

다음은 수행 과정에 대한 설명입니다.

1. cm1.tip과 cm2.tip은 “[TAC 구성](#tac)”을 참고해서 생성합니다.

다음 TIP 파일 내용에서 메모리 사이즈 등 다양한 수치들은 예제일 뿐이고, 사용 목적에 맞게 조정할 수 있습니다(본 예제에서는 raw 디바이스를 사용하지 않고, 각각의 용량이 5GB인 /data/disk01과 /data/disk02라는 두 파일을 사용하여 한 컴퓨터에 두 노드를 띄울 예정입니다). 디스크 구성은 "[Tibero Active Storage 관리자 안내서](/tibero-manuals/7.2.6.manuals/active-storage-guide.md)"의 "[디스크 준비](/tibero-manuals/7.2.6.manuals/active-storage-guide/appendix.md#undefined-1)"를 참조합니다.

<\<as1.tip>>

```
LISTENER_PORT=30011
MEMORY_TARGET=2G
MAX_SESSION_COUNT=50
TOTAL_SHM_SIZE=1G

CLUSTER_DATABASE=Y   # 필수
THREAD=0

CM_PORT=8635        # cm1의 CM_UI_PORT
LOCAL_CLUSTER_ADDR=123.1.1.1
LOCAL_CLUSTER_PORT=30111

INSTANCE_TYPE=AS    # 필수
AS_ALLOW_ONLY_RAW_DISKS=N   # RAW 디바이스를 사용하지 않으므로, 이 설정이 필요하다.

AS_DISKSTRING="/data/*"   # /data/disk01과 /data/disk02를 사용하므로 /data/* 값을 준다.
```

<\<as2.tip>>

```
LISTENER_PORT=40011
MEMORY_TARGET=2G
MAX_SESSION_COUNT=50
TOTAL_SHM_SIZE=1G

CLUSTER_DATABASE=Y   # 필수
THREAD=1

CM_PORT=8655        # cm2의 CM_UI_PORT
LOCAL_CLUSTER_ADDR=123.1.1.1
LOCAL_CLUSTER_PORT=40111

INSTANCE_TYPE=AS    # 필수
AS_ALLOW_ONLY_RAW_DISKS=N   # RAW 디바이스를 사용하지 않으므로, 이 설정이 필요하다.
AS_DISKSTRING="/data/*"     # /data/disk01과 /data/disk02를 사용하므로 /data/* 값을 준다.
```

2. TAS용 TIP 파일이 준비되면 1번 노드부터 순서대로 설정합니다.

먼저 1번 노드에서 export CM\_SID=cm1으로 환경변수를 설정합니다. 그 후, CM을 부팅하여 네트워크를 추가하는 곳까지 앞의 내용대로 수행하여 cmrctl show 커맨드를 수행하였을 때 다음과 같이 조회될 수 있도록 합니다.

```
Resource List of Node cm1
==============================================================
  CLUSTER    TYPE       NAME        STATUS        DETAIL
----------  --------  ----------  -----------  ------------------
   COMMON   network     net1        UP (private) 123.1.1.1/29000
==============================================================
```

3. 다음으로 클러스터를 등록해야 하는데, 다음과 같이 cfile 부분이 앞에서와 달라집니다.

```
cmrctl add cluster --name cls1 --incnet net1 --cfile "+/data/*"
```

4. 성공적으로 수행되었다면, TB\_SID를 as1으로 export한 후 다음 명령어를 수행하여 TAS 인스턴스를 기동합니다([“TAC 구성”](#tac)과 달리 클러스터를 start하지 않습니다).

```
tbboot nomount
```

5. 부팅이 완료되면 tbsql을 통해 TAS 인스턴스에 접속하여 다음 SQL로 디스크 스페이스를 만듭니다. TAS에서도 Tibero 또는 TAC와 마찬가지로 tbdsn.tbr에 as1의 설정을 써 주어야 tbsql로 인스턴스에 접속할 수 있습니다.

```
as1=(
        (INSTANCE=(HOST=123.1.1.1)
                 (PORT=30011)
        )
)
```

```
CREATE DISKSPACE ds0 NORMAL REDUNDANCY
  FAILGROUP fg1 DISK
    '/data/disk01' NAME disk101
  FAILGROUP fg2 DISK
    '/data/disk02' NAME disk201
  ATTRIBUTE 'AU_SIZE'='4M';
```

6. 수행 완료 후 tbsql을 종료하고, TAS 인스턴스도 종료되었음을 확인한 후 아래 명령어로 클러스터를 실행합니다.

```
cmrctl start cluster --name cls1
```

7. 그 후 cmrctl show를 이용해 리소스를 확인해 보면 다음과 같이 조회됩니다.

```
Resource List of Node cm1
==============================================================
  CLUSTER   TYPE      NAME     STATUS   DETAIL
---------- -------- ---------- -------- -----------------------
  COMMON    network   net1      UP       (private) 123.1.1.1/29000
  COMMON    cluster   cls1      UP       inc: net1, pub: N/A
   cls1     file      cls1:0    UP       +0
   cls1     file      cls1:1    UP       +1
   cls1     file      cls1:2    UP       +2
==============================================================
```

8. 이제 다음의 커맨드를 사용하여 as용 서비스 리소스를 등록합니다.

```
cmrctl add service --name as --cname cls1 --type as
```

9. 다음으로 as를 등록합니다. envfile은 tibero7/ 아래에 envfile\_for\_as1으로 저장하였고, --name의 값은 TIP 파일에 사용된 이름인 as1로 해야 합니다.

```
cmrctl add as --name as1 --svcname as --dbhome /home/tibero7
--envfile /home/tibero7/envfile_for_as1
```

10. 다음 명령어로 TAS 인스턴스를 NORMAL 모드로 부팅합니다.

```
cmrctl start service --name as
혹은
cmrctl start as --name as1
```

11. 위의 커맨드를 통해 TAS 인스턴스가 성공적으로 부팅되었으면, 다음과 같이 tbsql로 커맨드를 수행하여 2번 노드의 TAS 인스턴스가 사용할 스레드를 생성해야 합니다.

```
tbsql sys/tibero@as1
sql> alter diskspace ds0 add thread 1;
```

12. 여기까지 왔으면 나머지 2번 노드에서도 TAS 인스턴스를 띄울 준비가 완료된 것입니다.

2번 노드에서 `export CM_SID=cm2`와 `export TB_SID=as2` 명령어를 수행하여 환경 변수를 설정합니다. 그 후 tbcm -b로 CM을 부팅하고, 다음 명령어를 수행합니다(본 예제에서는 같은 컴퓨터에 두 노드를 구성하므로 네트워크의 ipaddr이 cm1에서와 같고 portno만 다릅니다).

```
cmrctl add network --name net1 --ipaddr 123.1.1.1 --portno 29100
cmrctl add cluster --name cls1 --incnet net1 --cfile "+/data/*"
cmrctl start cluster --name cls1
```

13. 이제 cmrctl show를 실행해보면 다음과 같이 서비스가 등록된 것을 확인할 수 있습니다.

```
Resource List of Node cm2
==============================================================
  CLUSTER   TYPE      NAME     STATUS   DETAIL
---------- -------- ---------- -------- --------------------------------------------
  COMMON    network   net1      UP       (private) 123.1.1.1/29100
  COMMON    cluster   cls1      UP       inc: net1, pub: N/A
   cls1     file      cls1:0    UP       +0
   cls1     file      cls1:1    UP       +1
   cls1     file      cls1:2    UP       +2
   cls1     service   as        UP       Active Storage, Active Cluster
                                       (auto-restart: OFF)
==============================================================
```

14. 다음 명령어로 AS를 등록한 후 2번 노드에서도 TAS 인스턴스를 실행합니다.

```
cmrctl add as --name as2 --svcname as --dbhome /home/tibero7
--envfile /home/tibero7/envfile_for_as2
cmrctl start as --name as2
```

15. 정상적으로 위 과정이 수행되었다면 각 노드에서의 cmrctl show의 결과는 다음과 같이 출력됩니다.

* 노드 1에서의 cmrctl show 결과

```
Resource List of Node cm1
==============================================================

  CLUSTER   TYPE      NAME      STATUS   DETAIL
---------- -------- ---------- -------- ------------------------------
  COMMON    network   net1      UP       (private) 123.1.1.1/29000
  COMMON    cluster   cls1      UP       inc: net1, pub: N/A
   cls1     file      cls1:0    UP       +0
   cls1     file      cls1:1    UP       +1
   cls1     file      cls1:2    UP       +2
   cls1     service   as        UP       Active Storage, Active Cluster
                                        (auto-restart: OFF)
   cls1     as        as1       UP       as, /home/tibero7

==============================================================
```

* 노드 2에서의 cmrctl show 결과

```
Resource List of Node cm2
==============================================================

  CLUSTER   TYPE      NAME      STATUS   DETAIL
---------- -------- ---------- -------- ------------------------------
  COMMON    network   net1      UP       (private) 123.1.1.1/29100
  COMMON    cluster   cls1      UP       inc: net1, pub: N/A
   cls1     file      cls1:0    UP       +0
   cls1     file      cls1:1    UP       +1
   cls1     file      cls1:2    UP       +2
   cls1     service   as        UP       Active Storage, Active Cluster
                                        (auto-restart: OFF)
   cls1     as        as2       UP       as, /home/tibero7

==============================================================
```

16. 두 노드에서의 TAS 구성이 완료되었습니다. 이제 각 노드에서 TAC 구성을 진행하면 됩니다. 먼저 각 노드의 $TB\_HOME/config에 ac1.tip과 ac2.tip을 만드는데, 내용은 다음과 같이 합니다.

<\<ac1.tip>>

```
DB_NAME=ac
LISTENER_PORT=21000
CONTROL_FILES="+DS0/c1.ctl","+DS0/c2.ctl"
DB_CREATE_FILE_DEST="+DS0"
LOG_ARCHIVE_DEST="/home/ac/data/archive1"

MEMORY_TARGET=1G
MAX_SESSION_COUNT=50
TOTAL_SHM_SIZE=512M

USE_ACTIVE_STORAGE=Y
AS_PORT=30011

CLUSTER_DATABASE=Y
THREAD=0
UNDO_TABLESPACE=UNDO0

LOCAL_CLUSTER_ADDR=123.1.1.1
CM_PORT=8635
LOCAL_CLUSTER_PORT=21100
```

<\<ac2.tip>>

```
DB_NAME=ac
LISTENER_PORT=21010
CONTROL_FILES="+DS0/c1.ctl","+DS0/c2.ctl"
DB_CREATE_FILE_DEST="+DS0"
LOG_ARCHIVE_DEST="/home/ac/data/archive2"

MEMORY_TARGET=1G
MAX_SESSION_COUNT=50
TOTAL_SHM_SIZE=512M

USE_ACTIVE_STORAGE=Y
AS_PORT=40011

CLUSTER_DATABASE=Y
THREAD=1
UNDO_TABLESPACE=UNDO01

LOCAL_CLUSTER_ADDR=123.1.1.1
CM_PORT=8655
LOCAL_CLUSTER_PORT=21110
```

17. TAC용 TIP 파일을 저장했으면, 각 노드에서 아래 명령어를 수행합니다(각 노드의 TB\_HOME에 envfile\_ac1과 envfile\_ac2를 만들었습니다. envfile에 대한 내용은 “cmrctl add”와 “[TAC 구성](#tac)”을 참고합니다).

* 1번 노드

```
cmrctl add service --name ac --cname cls1
cmrctl add db --name ac1 --svcname ac --dbhome /home/tibero7
--envfile /home/tibero7/envfile_ac1
```

* 2번 노드

```
cmrctl add db --name ac2 --svcname ac --dbhome /home/tibero7
--envfile /home/tibero7/envfile_ac2
```

18. 이제 1번 노드에서 “TAC를 위한 데이터베이스 생성”의 2번부터 6번까지 과정을 수행합니다. 이때 DB 인스턴스를 nomount 모드로 부팅하는 커맨드로 다음의 명령어를 사용합니다.

```
cmrctl start db --name ac1 --option "-t NOMOUNT"
```

또는

```
tbboot nomount
```

19. “TAC를 위한 데이터베이스 생성”의 6번까지 과정을 수행한 후 다음 명령어로 각 노드에 DB를 기동하여 TAS-TAC 구성을 마칩니다. 단, 데이터베이스를 생성하는 과정에서 logfile의 경로를 지정할 때에는 '+DS0/log001'(+는 TAS용 경로임을 표시하고, DS0는 앞서 생성한 디스크 스페이스 이름입니다.)과 같은 TAS용 경로를 사용해야 합니다.

```
cmrctl start service --name ac
```

## HA Service 구성

본 절에서는 HA(High Availability) 구성을 위해 Linux 환경에서 참고할 수 있는 예제를 설명합니다.

HA를 구성하는 방법은 TAC와 비슷하며, TIP 파일 설정과 서비스 리소스에 --mode ha가 들어가는 점만 다릅니다. 1번 노드의 TB\_SID는 ha1, CM\_SID는 cm1이고, 2번 노드의 TB\_SID는 ha2, CM\_SID는 cm2입니다.

1. cm1.tip과 cm2.tip은 “TAC 구성”과 같이 작성하고, ha1.tip과 ha2.tip만 다음과 같이 작성합니다(본 예제에서는 쉬운 설명을 위해 같은 컴퓨터에 두 노드를 기동했습니다).

<\<ha1.tip>>

```
DB_NAME=ha    #DB_NAME은 ac1과 ac2가 같은 값을 가진다.
LISTENER_PORT=25001
CONTROL_FILES="/home/tibero7/database/ha/c1.ctl"
DB_CREATE_FILE_DEST="/home/tibero7/database/ha"
LOG_ARCHIVE_DEST="/home/tibero7/database/ha/archive1"

MAX_SESSION_COUNT=20
TOTAL_SHM_SIZE=1G
MEMORY_TARGET=2G

CLUSTER_DATABASE=Y
THREAD=0
UNDO_TABLESPACE=UNDO0

LOCAL_CLUSTER_ADDR=123.1.1.1
LOCAL_CLUSTER_PORT=21100
CM_PORT=8635
```

<\<ha2.tip>>

```
DB_NAME=ha     #DB_NAME은 ac1과 ac2가 같은 값을 가진다.
LISTENER_PORT=35001
CONTROL_FILES="/home/tibero7/database/ha/c1.ctl"
DB_CREATE_FILE_DEST="/home/tibero7/database/ha"
LOG_ARCHIVE_DEST="/home/tibero7/database/ha/archive1"

MAX_SESSION_COUNT=20
TOTAL_SHM_SIZE=1G
MEMORY_TARGET=2G

CLUSTER_DATABASE=Y
THREAD=0        # TAC에서와 달리 ha1과 ha2가 같은 thread, UNDO_TABLESPACE 값을 가진다.
UNDO_TABLESPACE=UNDO0

LOCAL_CLUSTER_ADDR=123.1.1.1
LOCAL_CLUSTER_PORT=31100
CM_PORT=8655
```

2. HA용 TIP 파일이 준비되었으니, ha1과 ha2를 위한 envfile을 만든 후 다음과 같은 커맨드로 네트워크와 클러스터, 서비스, HA를 등록합니다.

**1번 노드**

```
export CM_SID=cm1
export TB_SID=ha1
tbcm -b
cmrctl add network --name net1 --ipaddr 123.1.1.1 --portno 29000
cmrctl add cluster --name cls1 --incnet net1 --cfile /home/tibero7/cfile/cls1_cfile
cmrctl start cluster --name cls1
cmrctl add service --name ha --cname cls1 --mode ha
cmrctl add db --name ha1 --svcname ha --dbhome /home/tibero7 --envfile /home/tibero7/envfile_ha1
```

**2번 노드**

```
export CM_SID=cm2
export TB_SID=ha2
tbcm -b
cmrctl add network --name net1 --ipaddr 123.1.1.1 --portno 29100
cmrctl add cluster --name cls1 --incnet net1 --cfile /home/tibero7/cfile/cls1_cfile
cmrctl start cluster --name cls1
cmrctl add db --name ha2 --svcname ha --dbhome /home/tibero7 --envfile /home/tibero7/envfile_ha2
```

3. 이제 운용할 데이터베이스를 만들어야 합니다.

먼저 NOMOUNT 모드로 부팅한 후 single Tibero에서와 같은 방식으로 데이터베이스를 생성합니다. 이때 역시 tbsql 접속을 위한 tbdsn.tbr 파일에 ha1을 추가해주어야 합니다. 그 후 system\_install.sh를 수행하면 데이터베이스 생성이 완료됩니다.

마지막으로 다음의 커맨드를 1번 노드에 적용하면 1번 노드가 다운되고 retry\_cnt만큼 재기동에 실패하여 DEACT 처리되었을 때 2번 노드에 DB 인스턴스가 실행되게 됩니다(1번 노드가 Active, 2번 노드를 Standby라고 하며 이는 cmrctl show service --name ha로 확인 가능합니다).

```
ha1=(
        (INSTANCE=(HOST=123.1.1.1)
                 (PORT=25001)
                 (DB_NAME=ha)
        )
)
```

```
cmrctl act service --name ha

cmrctl show service --name ha
Service Resource Info
=====================================

Service name        : ha
Service type        : Database
Service mode        : HA
Cluster             : cls1
Inst. Auto Start: ON
===========================
|   INSTANCE LIST        |
|------------------------|
| NID  Status  HA MODE   |
| ---  ------- -------   |
|   1   UP     Active    |
|   2  DOWN    Standby   |
===========================
```

만약 1번 노드가 다운되어 2번 노드가 자동 실행되면, 1번 노드가 deact되어 있을 수 있습니다. 이 경우 deact된 리소스를 act시켜주면 1번 노드가 standby가 되어 2번 노드를 failover하게 됩니다.

## CM Observer 구성

CM Observer는 Tibero-TSC 구조에서 관제 대상이 되는 CM들과의 통신을 토대로 TSC로의 failover 수행을 지원합니다. CM Observer는 그 관제 하의 CM과의 Heartbeat 및 DB 변화에 대한 메시지를 주고받으며, 이를 기반으로 failover의 실행을 결정합니다.

CM Observer를 구성하는 방법은 일반적인 CM을 구성하는 방식과 다릅니다. Observer는 CM TIP에 자신이 일반적인 CM이 아닌 Observer 노드로 동작함을 명시해 주어야 하며, 그 관제 하의 CM 노드들과 통신할 Observer port도 명시해 주어야 합니다.

관제 하의 CM은 TSC 구성을 한 후 DB 서비스를 등록할 때에 Observer의 ip, port 및 TSC ID를 명시해 주어야 하며(CM은 이 과정을 통해 Observer에 등록됩니다.) 또한 DB는 TIP 파일에 몇몇 파라미터를 적용해 주어야 합니다. 나머지는 일반적인 TSC 구성과 유사합니다.

Observer는 관제 대상 CM, Instance들과 독립된 HW에서 동작시켜야 하며, Observer가 동작하는 장비는 troubleproof해야 합니다. 만약 독립된 HW가 아닌 경우 기능이 제한될 수 있습니다. 또한 한 TSC 내의 CM들은 서로 다른 CM NAME을 가져야 합니다.

### 환경 변수 설정

CM Observer도 CM과 마찬가지로 환경 변수 CM\_HOME과 CM\_SID를 설정해야 합니다. 다음은 설정 예입니다.

<table><thead><tr><th width="189">환경 변수</th><th>설명</th></tr></thead><tbody><tr><td>$CM_HOME</td><td><p>CM Observer가 설치된 경로로 지정</p><p><br>예)<code>export CM_HOME=/home/tibero7</code></p></td></tr><tr><td>$CM_SID</td><td><ul><li>노드를 식별할 수 있는 ID를 지정</li><li>각 노드는 서로 다른 값을 가져야 함</li></ul><p><br>예)<code>export CM_SID=cmobs</code></p></td></tr></tbody></table>

### 파라미터 설정

CM Observer용 초기화 파라미터와 Observer를 사용하는 경우 필수 DB 파라미터에 대해서 설명합니다.

#### **초기화 파라미터**

CM Observer용 TIP에는 다음과 같은 파라미터들을 설정할 수 있습니다. 필수 항목은 사용자가 TIP에 명시적으로 값을 지정해야 하며, 선택 항목은 사용자가 지정하지 않을 수 있고 이 경우 기본값으로 입력됩니다.

<table><thead><tr><th width="244">초기화 파라미터</th><th width="90">필수 여부</th><th>설명</th></tr></thead><tbody><tr><td>CM_NAME</td><td>필수</td><td><ul><li>Observer의 identifier로 쓸 이름</li><li>서로 다른 노드의 CM은 다른 값을 가져야 함</li></ul></td></tr><tr><td>CM_MODE_OBSERVER</td><td>필수</td><td>CM 노드가 Observer 모드로 동작함을 명시해주어야 함 (Y로 설정)</td></tr><tr><td>CM_UI_PORT</td><td>필수</td><td><ul><li>cmrctl 명령어 수행할 때에 CM으로 접속하는 용도로 사용할 네트워크 포트 번호</li><li>이 포트는 노드 간에 열려있어야 함</li></ul></td></tr><tr><td>CM_OBSERVER_PORT</td><td>필수</td><td>CM Observer와 그 관제 대상 CM들과 연결하기 위한 용도로 사용할 네트워크 포트 번호</td></tr><tr><td>CM_OBSERVER_EXPIRE</td><td>선택</td><td><ul><li>CM Observer expire란 관제 하의 CM에 문제가 생겼다는 것을 CM Observer가 알아차리는 데 필요한 표준 시간을 의미</li><li>즉, 관제 하의 CM 중 Heartbeat expire 시간이 지나도록 통신이 되지 않는 CM이 있으면, CM Observer는 통신이 되지 않는 노드의 CM에 문제가 생겼다고 인식하게 됨</li><li>이 값은 CM_HEARTBEAT_EXPIRE와 CM_NET_EXPIRE_MARGIN을 더한 값보다 작아야 함 (단위: 초(second), 기본값: 60)</li></ul></td></tr><tr><td>LOG_LVL_CM</td><td>선택</td><td><ul><li>CM이 로그를 남기는 수준을 지정</li><li>값이 높을수록 CM이 더 많은 로그를 저장하며, 1~6 사이의 정수값을 가질 수 있음(기본값: 2)</li></ul></td></tr><tr><td>CM_LOG_DEST</td><td>선택</td><td><ul><li>CM이 로그를 남길 디렉터리를 지정</li><li>이 값은 반드시 절대 경로여야 함<br>(기본값: $CM_HOME/instance/$CM_SID/log/)</li></ul></td></tr><tr><td>CM_LOG_FILE_SIZE</td><td>선택</td><td><ul><li>CM 로그 파일의 최대 크기(용량)를 지정</li><li>로그가 계속 생성되어 파일의 크기가 이 값을 넘어서려 할 경우 현재의 로그 파일이 닫히고, 새로운 파일이 생성되어 그 파일에 로그가 저장</li><li>값은 100KB~1GB 사이의 정수값을 가질 수 있음 (단위: Byte, 기본값: 10MB)</li></ul></td></tr><tr><td>CM_LOG_TOTAL_SIZE_LIMIT</td><td>선택</td><td><ul><li>CM_LOG_DEST에서 지정한 디렉터리에 생성되는 로그 파일들의 크기 총합의 최대값을 지정</li><li>로그 파일들의 크기의 합이 이 값을 넘어가게 되면, 가장 오래된 파일을 삭제함으로써 파일 용량이 끝없이 증가하는 것을 막음</li><li>이 값은 100KB~1GB 사이의 정수값을 가질 수 있음 (단위: Byte, 기본값: 300MB)</li></ul></td></tr><tr><td>CM_TIME_UNIT</td><td>선택</td><td>CM을 컨트롤할 때 사용되는 단위 시간의 길이를 지정 (단위: 0.1초, 기본값: 10)</td></tr></tbody></table>

#### **필수 DB 파라미터**

CM Observer를 정상적으로 사용하기 위해 DB TIP에 Observer에 대한 파라미터를 설정해야 합니다.

<table><thead><tr><th width="273">파라미터</th><th>설명</th></tr></thead><tbody><tr><td>STANDBY_USE_OBSERVER</td><td>일반적인 Tibero-TSC 구조에서 Observer를 통해 관제 및 Failover를 진행할지를 결정(필수 설정 값: Y)</td></tr></tbody></table>

### CM Observer 실행

CM Observer 데몬 실행 이후의 작업들은 cmrctl 명령어를 사용하여 수행합니다. CM Observer는 다음의 방법으로 실행합니다.

* \[option]

<table><thead><tr><th width="162">옵션</th><th>설명</th></tr></thead><tbody><tr><td>-b</td><td>CM Observer 데몬을 실행</td></tr><tr><td>-d</td><td>CM Observer 데몬을 종료</td></tr><tr><td>-s</td><td><ul><li>CM Observer의 상태를 보여줌</li><li>초기화 파라미터에 등록된 내용이 표시됨</li></ul></td></tr><tr><td>-h</td><td>tbcmobs 명령어에 대한 도움말을 보여줌</td></tr></tbody></table>

### **Observer** 명령어

cmrctl은 New CM 및 Observer에서 리소스들을 관리 및 제어하기 위해 사용하는 명령어 set입니다. 단 지원하는 명령의 종류는 New CM일 때와 Observer일 때 서로 다르며, Observer에서 지원하는 cmrctl 명령어 용법은 다음과 같습니다.

#### **cmrctl show**

Observer에 등록된 리소스의 정보를 확인하기 위한 명령어입니다. 다음의 2가지 방법으로 사용이 가능합니다.

**방법 1)**

```
cmrctl show
```

현재 CM Observer에 등록된 CM 및 DB Instance들의 목록을 출력합니다.<br>

**방법 2)**

```
cmrctl show --tscid <tscid>
```

지정한 특정 TSC의 상세한 정보를 출력합니다.

#### **cmrctl set**

Observer에 등록된 TSC의 동작을 설정하기 위한 명령어입니다. 다음의 3가지 방법으로 사용이 가능합니다.

**방법 1)**

```
cmrctl set --tscid <tscid> --<type> <act_var>
```

위의 명령 상으로 지원하는 type과 act\_var는 다음과 같습니다.

<table><thead><tr><th width="167"></th><th width="147"></th><th></th></tr></thead><tbody><tr><td>auto_failover</td><td>on</td><td>해당 TSC의 autofailover를 수행 (기본값)</td></tr><tr><td>auto_failover</td><td>off</td><td>해당 TSC의 autofailover를 수행하지 않음</td></tr><tr><td>mode</td><td>protective</td><td>해당 TSC에 대한 Auto Failover의 동작방식을 protective 모드로 설정 (기본값)</td></tr><tr><td>mode</td><td>disaster_plan</td><td>해당 TSC에 대한 Auto Failover의 동작방식을 disaster_plan 모드로 설정</td></tr></tbody></table>

* 방법 2)

```
cmrctl set --tscid <tscid> --target <target_clsid / mr>
```

지정한 특정 TSC의 failover 대상(Target)을 특정 클러스터로 설정(고정)하거나, 가장 최신의 TSN을 받은(Most Received) 클러스터가 failover 대상(Target)이 되도록 합니다.

* 방법 3)

```
cmrctl set --tscid <tscid> --target <target_clsid / mr> --auto_failover <act_var>
```

Failover 대상 클러스터 설정 및 auto\_failover 여부를 설정합니다.

#### **cmrctl switchover**

지정된 tsc를 switchover하기 위한 명령어입니다. 다음의 2가지 방법으로 사용이 가능합니다.

* 방법 1)

```
cmrctl switchover --tscid <tscid>
```

현재 Target 클러스터로 switchover를 수행합니다.

* 방법 2)

```
cmrctl switchover --tscid <tscid> --target <target_clsid>
```

지정한 Target 클러스터로 switchover를 수행합니다.

### **Observer** 구성 예시

다음은 Observer를 구성하는 과정에 대한 설명입니다.

1. CM TIP 파일의 설정과 DB TIP 파일의 설정은 “[TAC-TSC 구성](/tibero-manuals/7.2.6.manuals/administrator-guide/tibero-standby-cluster.md#tac-tsc)”을 참고하여 작성합니다.
2. 다음은 Observer TIP 파일의 예시입니다.

<\<cmobs.tip>>

```
CM_NAME=cmobs
CM_MODE_OBSERVER=Y     # Observer로 기동시킬 것이기에 반드시 설정해야 합니다.
CM_OBSERVER_PORT=14500 # 관제 하의 CM 노드에서 service를 등록할 때 이 port를 사용합니다.
CM_UI_PORT=13500

# Observer는 resource file이 없습니다.
# 따라서 Resource file의 경로를 지정할 필요가 없습니다.
```

다음은 일반적인 CM TIP 파일의 예시입니다.

<\<cm1.tip>>

```
CM_NAME=cm1
CM_UI_PORT=27500
CM_RESOURCE_FILE=/home/tibero/cm1_res
CM_HEARTBEAT_EXPIRE=120
CM_WATCHDOG_EXPIRE=110

# Observer가 아닌 CM은 resource file이 필요하다.
# 따라서 Resource file의 경로를 지정해야 합니다.
```

3. Observer용 TIP 파일 및 다른 CM, DB TIP 파일들이 준비되었으니, 네트워크와 클러스터, 서비스, DB를 등록합니다. 대부분의 등록 과정은 “TAC-TSC 구성”과 같습니다. 단, DB 서비스 등록 과정이 약간 상이하나, 아래의 예시와 같이 서비스 등록 과정에서 이를 관제할 Observer의 ip와 port, TSC ID를 명시해주어야 합니다(본 예제에서는 쉬운 설명을 위해 같은 컴퓨터에 옵저버와 노드를 띄웠습니다).

– Observer 미사용 시 DB 서비스 등록

```
cmrctl add service --type db --name tac --cname cls0
```

– Observer 사용 시 DB 서비스 등록(관제 대상 CM 노드에서 서비스 등록 시)

```
cmrctl add service --type db --name tac --cname cls0
                   --tscid 11 --obsip 127.0.0.1 --obsport 14500
```

관제 대상 CM은 이를 통해 Observer에 등록됩니다.

4. 구성이 완료되면 Observer에서 cmrctl show 명령을 통해 아래와 같이 TSC가 구성되었음을 확인할 수 있습니다.

– Observer가 관제하는 CM 및 DB Instance 확인

```
cmrctl show

Resource List of Observer cmobs
================================================================
 TSC_ID   CLS_ID   CM_NAME   NID   CM_STAT   INST_STAT   PRI/TAR
 -------  -------  --------  ----  --------  ----------  --------
   11        0       cm0       1      UP       UP(NRML)   PRIMARY
             1       cm0_sb    1      UP       UP(RECO)   TARGET
================================================================
```

– 특정 TSC에 대한 정보 확인

```
cmrctl show --tscid 11

TSC(ID: 11) Information
============================================================================
 FAILOVER   MODE        CLS_ID   CM_NAME   CONN   LOG   Heartbeat   RCVD.TSN
 ---------  ----------  -------  --------  -----  ----  ----------  ---------
 ON(TSN)    PROTECTIVE     0       cm0      Y(M)    -       60         0
                           1       cm0_sb   Y(M)    1       60        13655
============================================================================
```

### Observer 동작

다음은 Observer 동작을 위한 설정값에 대한 설명입니다.

* Observer에 등록된 클러스터의 분류

<table><thead><tr><th width="173">설정 값</th><th>설명</th></tr></thead><tbody><tr><td>Primary</td><td><ul><li>Normal 모드로 부팅한 Tibero가 포함된 클러스터이며, 한 TSC 안에 복수의 Primary 클러스터는 존재할 수 없음</li><li>만약 Normal 모드로 부팅한 Tibero가 포함된 클러스터가 복수 개라면 모두 Primary 지위를 박탈당함</li></ul></td></tr><tr><td>Standby</td><td>Primary와 Observer가 등록한 Standby 클러스터이며, 한 TSC 안에서 여러 클러스터가 Standby일 수 있음</td></tr><tr><td>Target</td><td>Standby로 등록된 클러스터 중 auto failover의 대상이 될 클러스터이며, 한 TSC 안에는 단 하나의 Target 클러스터만 존재할 수 있음</td></tr><tr><td>N</td><td>위의 종류에 속하지 않는 클러스터</td></tr></tbody></table>

* Auto Failover 여부

<table><thead><tr><th width="180">설정 값</th><th>설명</th></tr></thead><tbody><tr><td>OFF</td><td><ul><li>Primary가 종료되어 auto failover를 하지 않음</li><li>또한 Primary는 어떠한 경우에도 스스로 종료되지 않음</li></ul></td></tr><tr><td>ON(TSN)</td><td>Standby 클러스터 중 received tsn이 가장 높은 Standby 클러스터를 auto failover의 대상(target)으로 설정</td></tr><tr><td>ON(FIXED)</td><td>사용자가 지정한 Standby 클러스터를 auto failover의 대상(target)으로 설정</td></tr></tbody></table>

* Auto Failover 모드

<table><thead><tr><th width="178">설정 값</th><th>설명</th></tr></thead><tbody><tr><td>PROTECTIVE</td><td><ul><li>Primary 클러스터의 안정성을 최우선으로 하는 모드로써, 어떠한 경우에도 Primary 클러스터는 스스로 종료하지 않음</li><li>그러나 정전 등의 이유로 관제 대상 CM까지 종료되어 버리는 경우에는 auto failover가 일어나지 못함</li><li>즉, Observer와 CM과의 접속이 유효할 때만 DB Instance의 상황에 따라 auto failover를 수행할 수 있음 (기본값)</li></ul></td></tr><tr><td>DISASTER_PLAN</td><td><ul><li>재난대비 모드로써, Primary 클러스터 전체가 재난 등으로 종료되었을 때도 failover를 수행할 수 있음</li><li>즉, Primary 클러스터의 CM들이 모두 Observer와 연결이 끊겨도 auto failover가 가능</li><li>그러나 Observer와 Primary 클러스터간 통신이 단절되었으며 CM_OBSERVER_EXPIRE 시간 동안 복구가 되지 않는 경우 Primary 클러스터의 DB를 CM이 스스로를 종료 시킬 수 있음​</li></ul></td></tr></tbody></table>

### **Observer** 사용 시 고려 사항

Observer를 사용하는 경우 기동과 종료는 다음의 순서를 따릅니다.

* 기동
  1. Observer 기동
  2. Primary, Standby CM 기동 후 Observer에서 Primary, Standby CM 접속 확인 (observer cmrctl show)
  3. Primary, Standby Tibero 인스턴스 기동 후 Observer에서 정상적인 상태 확인 (Primary/Standby/Target)
* 종료
  1. Observer 종료
  2. Primary, Standby Tibero 인스턴스 종료
  3. Primary, Standby CM 종료

## **CM STONITH** 기능 구성

CM의 cluster 구성에서 어떤 노드의 문제가 발생하게 된다면 schedule out이 진행됩니다. Schedule out 과정에서 해당 노드가 이미 종료되어 있지 않다면 해당 노드에게 schedule out 사실을 알려주고 종료 과정을 수행하도록 합니다. 그 후 cluster에 속한 resource들의 재구성이 시작됩니다.(ex. service reconfiguration)

이때, 해당 노드가 hang이 걸려 종료를 처리하지 못하는 경우가 발생할 수 있습니다. 이 경우 cluster에 속한 resource가 재구성되었을 때, schedule out 되었지만 아직 종료 과정을 완료하지 못한 노드에 의해 오류가 발생하게 됩니다. 이를 해결하는 간단한 방법은 해당 노드가 종료를 알려오는 것을 기다리는 방식입니다. 하지만 hang이 1-2시간 이상 지속되는 경우라면, 기다리는 해결법은 장시간 service 불가를 유발하게 됩니다. 따라서 정상 동작(cluster의 master로서 여러 동작들 수행) 중인 master 노드에서 schedule out된 노드가 cluster의 공유 볼륨에 접근하는 것을 차단하는 기능을 개발하게 되었습니다.

각 사용법을 확인 후 “[STONITH 기능 주의 사항](#stonith)” 부분을 반드시 참고해야 합니다.

### **sg\_persist**를 사용하는 **STONITH** 기능

#### **개요**

본 기능의 경우 sg\_persist라는 툴을 사용하여 진행됩니다. sg\_persist는 device에 registration & reservation을 수행하기 위한 SCSI PERSISTENT RESERVE 명령어를 날려주는 툴입니다. 간단하게 설명하면 각 노드는 device에 registration을 통해 자신의 key를 등록할 수 있고 이 key를 이용해 해당 device의 접근 방식을 reservation할 수 있습니다. 기본적으로 write exclusive mode, 즉 key를 등록한 노드만 write를 할 수 있는 모드로 설정했습니다. 그리고 어떤 node가 schedule out 시 해당 node의 key를 제거함으로써 더 이상 device에 write를 수행하지 못하도록 만들었습니다. 이를 통해 schedule out된 노드가 공유 볼륨을 접근해서 유발되는 문제를 차단할 수 있게 됩니다.

자신의 노드에서 종료를 진행하는 기존의 fencing 방식과 달리 sg\_persist를 이용하면 다른 노드에서 fencing을 진행하게 됩니다. 이러한 방식을 일반적으로 STONITH(Shoot The Other Node In The Head)라고 부릅니다.

#### **설정 방법**

**device**를 **multipath**를 이용하여 구성했을 경우, **“mpathpersist**를 사용하는 **STONITH** 기능” 설명을 참고합니다.

sg\_persist를 사용하기 위해서는 관련 툴이 설치되어 있어야 합니다. 아래 명령어를 통해 관련 툴이 설치되어 있는지 확인 가능합니다.

```
$ rpm -qa | grep sg3_utils
// 혹은
$ dpkg --get-selections | grep sg3_utils
// 또는  다른  패키지  확인  명령어
```

설치되어 있지 않은 경우, 설치 명령어를 통해 설치를 진행해야 합니다.

```
$ sudo yum install sg3_utils
// 또는 다른 설치 명령어를 통한 sg3_utils 설치
```

sg\_persist가 최신 버전으로 올라가며 여러 가지 오류 수정이 있어 아래와 같이 버전 업데이트를 수행해야 합니다. (2020년 이후 출시 버전을 추천합니다.)

```
$ yum update sg3_utils
// 혹은 다른 버전 업데이트 명령어
```

sg\_persist를 사용하기 위해서는 **CM**의 **root** 권한 기동이 필요합니다.

**CM tip**에 관련 IPARAM 설정이 필요합니다.

```
$ cat cm.tip
_CM_STONITH_THREAD=Y
...
```

cluster add 시 --stonith 옵션을 통해 관리할 디바이스 목록을 입력해 주어야 기능이 동작합니다. 이 옵션의 경우 모든 **cluster**에서 입력해야 하며 입력하지 않을 경우 cluster join이 거부됩니다. 각 cluster에서 입력한 디바이스 목록은 동일 디바이스를 가리키고 있어야 하며 그렇지 않을 경우 이상 동작을 하게 됩니다.

아래와 같은 방식으로 옵션을 추가하여 입력합니다.

```
$ cmrctl add cluster --name cls1 --incnet net1 --stonith "/dev/raw/raw5[0-8]"
--cfile "+/dev/raw/raw5[0-8]"
```

\
추가한 정보를 확인하는 방법은 다음과 같습니다.

```
$ cmrctl show cluster --name cls1 --option stonith
```

### **mpathpersist**를 사용하는 **STONITH** 기능

#### **개요**

서버에서 한 device에 대해 물리적으로 분리된 여러 I/O path를 가지게 할 수 있고 이를 device mapper multipath 기능이라고 합니다. 이 multipath로 구성된 device에 대해서 Linux의 경우 sg\_persist의 multipath 전용의 mpathpersist라는 툴을 이용합니다. 해당 툴의 경우 **Linux**에서만 동작이 확인되었으며, **Solaris** / **HP-UX** 등은 별도의 테스트가 필요합니다. 또한, Linux의 경우에도 /etc/multipath.conf에 설정할 내용 중 **Red Hat 7.5** 이상 버전에서만 동작하는 내용이 있어 우선 7.5 이상 버전에서만 지원하고 있습니다. (7.5 release date 2018-04-10) (cat /etc/redhat-release 로 OS 버전 확인이 가능합니다.)

#### **설정 방법**

mpathpersist가 최신 버전으로 올라가며 여러 가지 오류 수정이 있어 아래와 같이 버전 업데이트를 수행해야 합니다. (2020년 이후 출시 버전을 추천합니다.)

```
$ yum update device-mapper-multipath // 혹은  다른  버전  업데이트  명령어
```

sg\_persist 버전과 마찬가지로 **root** 권한 기동이 필요합니다. 루트 권한으로 /etc/multipath.conf 의 defaults란에 reservation\_key file 옵션 추가가 필요합니다.

```
# cat /etc/multipath.conf
...
defaults {
    ...
    reservation_key file
}
...
```

그 후 루트 권한으로 아래 명령어를 수행합니다.

```
# service multipathd reload
```

reload 후 루트 권한으로 multipath -ll 을 입력해 보았을 때 정상적으로 뜨지 않고 config file parsing 실패와 같은 에러 message가 뜬다면 옵션을 지원하지 않는 버전이므로 /etc/multipath.conf의 reservation\_key file을 지우고 service multipathd start를 수행해 주어야 합니다.

**CM tip**에 관련 IPARAM 설정이 필요합니다.

```
$ cat cm.tip
_CM_STONITH_THREAD=Y
_CM_STONITH_SG_CMD=mpathpersist
...
```

sg\_persist 사용 시와 마찬가지로 cluster add 시 --stonith 옵션을 통해 관리할 디바이스 목록을 입력해 주어야 기능이 동작합니다. 이 옵션의 경우 모든 **cluster**에서 입력해야 하며 입력하지 않을 경우 cluster join이 거부됩니다. mpathpersist를 쓸 경우 cluster add 시 --stonith 옵션의 입력값으로 multipath 경로를 입력해야 합니다.

multipath -ll을 통해 나오는 경로로 --stonith "/dev/mapper/mpatha" 혹은 --stonith "/dev/dm-3" 와 같이 입력해야 합니다. 해당 경로를 별도로 링크를 걸어둔 상태라면 그 링크를 입력해도 무방합니다.

```
$ cmrctl add cluster --name cls1 --incnet net1 --pubnet pub1
--stonith "/dev/mapper/mpatha" --cfile "+/dev/raw/raw5[0-8]"
```

### STONITH 기능 주의 사항

#### **스토리지 관련 주의사항**

스토리지가 SCSI-3 Persistent Reservation을 지원해야 합니다. 만약 지원하지 않는다면, 일반적으로 `--stonith` 옵션을 준 cluster add가 실패하고 기능을 사용할 수 없음을 의미합니다.

스토리지가 별도의 툴을 통하여 이미 관리되고 있는 상태라면 사용할 수 없습니다. 해당 툴과 어떠한 문제를 일으킬지 모르기 때문입니다.

#### **기능 사용 관련 주의사항**

본 기능은 기본적으로 지속적으로 사용하는 것을 가정하여 만들어졌습니다. 따라서 전체 노드를 종료하더라도 device에 등록된 정보가 남아 있으며, 새로 CM이 기동하여 cluster가 최초 기동할 때, 이 정보를 초기화하고 재등록하게 됩니다.

만약 전체 cluster 종료 후 cluster에 stonith 옵션으로 입력한 device에 대해 어떠한 작업을 수행해야 한다면, 아래 기술할 stonith 기능 해제 방법을 참고하여 해제 후 수행하거나 작업할 노드의 CM 기동 후 cluster 수준까지 기동하여 노드가 권한을 가져온 후 수행해야 합니다.

혹은 기능을 사용하다 사용하지 않게 될 경우 device에 등록된 정보를 제거해 주어야 하며 이 방법은 다음과 같습니다.

**아래 동작들은 반드시 전체 cluster가 종료된 후 수행되어야 합니다.**

device에 등록된 정보를 제거하는 과정이며 해당 device가 공유 볼륨이라 한 노드에서만 수행해도 전체에 적용이 되어 sg\_persist, mpathpersist 방법 모두 한 노드에서만 수행하면 됩니다.

1. CM에 등록된 정보를 이용하여 제거 (반드시 **cluster stop** 상태에서 수행해야 함)

   ```
   $ cmrctl deact cluster --name cls1 --option clear
   ```
2. sg\_persist 명령어를 이용하여 제거 (루트 권한 필요)

   ```
   # sg_persist --out --register-ignore --param-sark=434d [device 경로]
   # sg_persist --out --clear --param-rk=434d [device 경로]
   ```

device 경로에 /dev/raw/raw\*와 같이 hint를 주는 것은 동작하지 않으며 device 개수마다 별도로 수행해 주어야 합니다.

mpathpersist의 경우 sg\_persist 부분을 mpathpersist로 대체하면 됩니다.

## **CM** 에이전트 구성

CM 에이전트는 TAC 구조에서 CM이 리소스 관리 및 failover 기능이 필요한 프로그램을 등록하여 사용할 수 있습니다. (ex. prosync)

### 파라미터 설정

CM 에이전트에서 사용되는 파라미터에 대해서 설명합니다.

<table><thead><tr><th>파라미터</th><th width="92">필수 여부</th><th>설명</th></tr></thead><tbody><tr><td>CM_ID</td><td>선택</td><td><ul><li>CM을 식별하기 위해 고유 번호를 설정</li><li>에이전트에서 특정 CM을 지정하기 위해 사용(기본값: -1)</li></ul></td></tr><tr><td>CM_AGENT_THREAD_CHECK_EXPIRE</td><td>선택</td><td>에이전트 스레드가 동작하지 않는 시간을 확인하기 위한 파라미터로 CM_AGENT_THREAD_INTERVAL보다 4배 이상 값을 권고하고, cmrctl check agent로 정상/비정상을 확인할 수 있음<br>(기본값: 40s)</td></tr><tr><td>CM_AGENT_THREAD_INTERVAL</td><td>선택</td><td>에이전트 스레드가 반복하여 동작하는 주기(기본값: 10s)</td></tr></tbody></table>

### **CM** 에이전트 **count** 값

CM 에이전트에서 사용하는 count 값 설명으로 cmrctl show agent에서 확인 가능합니다.

<table><thead><tr><th width="245">count</th><th>설명</th></tr></thead><tbody><tr><td>MAX retry count</td><td>cmrctl add 명령어에서 입력한 --retry_cnt에 해당하는 값</td></tr><tr><td>Failed retry count</td><td>probe를 제외한 명령어 실패한 횟수</td></tr><tr><td>Probe retry count</td><td>probe 명령어 실패한 횟수</td></tr><tr><td>start retry count</td><td>cmrctl start 명령어 실패한 횟수</td></tr><tr><td>Abnormal count</td><td>script가 문제가 생겨서 실패한 횟수</td></tr></tbody></table>

### **CM** 에이전트 명령어

cmrctl은 New CM에서 리소스들을 관리 및 제어하기 위해 사용하는 명령어입니다. 에이전트와 관련된 명령어 사용법은 다음과 같습니다.

#### **cmrctl act**

다음의 이유로 인해 deactivate된 리소스를 다시 activate시켜주기 위한 명령어입니다.

* 에이전트를 추가할 때 입력한 --retry\_cnt(기본값: 3) 이상 start를 수행했는데도 실패한 경우
* 사용자가 cmrctl deact 명령어를 명시적으로 사용하여 비활성화시킨 경우
* 에이전트를 추가할 때 입력한 --script에 문제가 있는 경우

  * 입력한 경로에 스크립트 파일이 없는 경우
  * 스크립트의 실행 권한이 없는 경우
  * 스크립트가 문제가 생겨 timeout될 경우

  ```
  cmrctl act agent --name <agent_resource_name>
  ```

#### **cmrctl modify**

그룹 리소스의 failover 기능 사용 여부를 수정하기 위한 명령어입니다.

```
cmrctl modify group --name <group_resource_name> --failover <true|false>
```

### **CM** 에이전트 스크립트 설정 예시

cmrctl add agent 등록 시 --script에 입력한 스크립트 파일에 대한 예시입니다.

<<$TB\_HOME/agent0.sh>>

```
#!/bin/sh
# AGENT_HOME은 프로그램에게 명령어를 보내야하기 때문에 실행될 바이너리의 PATH를 설정
export AGENT_HOME=

# CMD는 사용자가 등록한 프로그램의 명령어를 입력합니다.
export CMD=

export logdir=$TB_HOME/instance/agent
mkdir -p $logdir

echo "`date +%Y/%m/%d\ %H:%M:%S` cm agent start (agent command $1)" \
>> $logdir/cmagent.log
case $1 in
START)
        # 프로그램을 시작시킬 명령어
        echo "start $CMD" >> $logdir/cmagent.log
        start $CMD
        rc=$?
        ;;
PROBE)
        # 프로그램이 정상적으로 동작하고 있는지 확인할 수 있는 명령어
        echo "probe $CMD" >> $logdir/cmagent.log
        probe $CMD
        rc=$?
        ;;
DOWN)
        # 프로그램을 종료시킬 명령어
        echo "down $CMD" >> $logdir/cmagent.log
        down $CMD
        rc=$?
        ;;
KILL)
        # 프로그램을 강제종료시킬 명령어
        echo "stop $CMD" >> $logdir/cmagent.log
        stop $CMD
        rc=$?
        ;;
NOTI)
        # CM이 프로그램에게 상태 변경 NOTI
        echo "noti $CMD" >> $logdir/cmagent.log
        noti $CMD
        rc=$?
        ;;
COMMIT)
        # CM이 클러스터에 속한 프로그램에게 모두 NOTI를 받은 이후 COMMIT
        # COMMIT이 되어야 failover 진행
        echo "commit $CMD" >> $logdir/cmagent.log
        commit $CMD
        rc=$?
        ;;
*)
        ;;
esac
echo "`date +%Y/%m/%d\ %H:%M:%S` cm agent end (agent command $1)" \
>> $logdir/cmagent.log

exit $rc
```
