SAP Service Startup 과정에 이어서, SAP HANA DB Startup 과정에 대해서도 정리한다.
여기까지는 기존 SAP Service Startup 과정과 동일하다.
OS 부팅 후, init 프로세스에 따라 sapinit 서비스가 수행되면서, /usr/sap/sapservices 파일을 읽어와 환경변수 세팅과 함께, sapstartsrv 프로세스가 시작된다.
이후 HANA DB 서비스 시작 명령어(HDB start, sapcontrol) 수행에 따라서 sapstart 프로그램이 수행된다.
sapstart 프로그램은 실제 SAP HANA 시스템을 구동하기 위해, HDB Daemon 프로세스(hdbdaemon) 를 수행한다.
HDB Daemon 프로세스는 daemon.ini 파일을 읽어와 정의된 SAP HANA Service 들을 runlevel 단계에 맞게 수행한다.
daemon_<hostname>.3<Instance number>00.XXX.trc
...
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000000 i Basis TraceStream.cpp(00000) : ==== Starting hdb.sap<SID>_HDB<InstNum>, version 2.00.XXX.00.0000000000 (fa/hana2spXX), build <OS Platform> <Hash Value> 2000-01-01 00:00:00 ...
...
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000001 i Daemon MainImpl.cpp(00000) : * hdbdaemon configuration file "/usr/sap/<SID>/HDB<InstNum>/<Hostname>/daemon.ini"
...
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000002 i Daemon Daemon.cpp(00000) : Line up current runlevel 0 to 5; next event "check" due in 10000 ms
...
기본적으로 위 순서의 Runlevel 이 daemon.ini 에 설정되어 있으며, 구성이나 설정에 따라 조금 차이가 있을 수 있다.
아래 설명은 위 단계를 따라 설명한다.
Runlevel 의 첫 단계는 Nameserver 다.
Nameserver 는 SYSTEMDB 의 핵심 서비스이며, 항상 첫번째로 시작하게 된다.
daemon_<hostname>.3<Instance number>00.XXX.trc
...
### Runlevel 0 시작
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000003 i Daemon Daemon.cpp(00000) : Runlevel 0 started
...
### nameserver 서비스 시작
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000004 i Daemon Program.cpp(00000) : Update runlevel of program 'nameserver', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000005 i Daemon Program.cpp(00000) : Instance 0 of program 'nameserver' will be started in 0 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000005 i Daemon Program.cpp(00000) : Starting instance right now
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000006 i Daemon DaemonChild.cpp(00000) : Starting program 'hdbnameserver' with args ''
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000007 i Daemon DaemonChild.cpp(00000) : Child program 'hdbnameserver', pid 00000 started in its own process group
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000008 i Daemon RunningInstance.cpp(00000) : Start 'hdbnameserver' as process 00000, process group 00000, instance 0 of <HDB Nameserver>
...
### nameserver 서비스 시작 중...
...
### 내부 소켓통신으로 nameserver 상태 체크 -> Return msg "started"
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000009 i Daemon NetworkListener.cpp(00000) : New connection accepted from 127.0.0.1/00000_tcp over socket 13
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000010 i Daemon NetworkConnection.cpp(00000) : Connection from 127.0.0.1/00000_tcp socket 13 pid 00000 'hdbnameserver'. Received message "started"
### nameserver 서비스 시작완료
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000011 i Daemon DaemonHandle.cpp(00000) : Program 'hdbnameserver', pid 00000 is started
### Runlevel 수정 (0->1)
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000012 i Daemon DaemonHandle.cpp(00000) : Last instance in runlevel 1 started
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000013 i Daemon Program.cpp(00000) : Update runlevel of program 'nameserver', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000014 i Daemon Daemon.cpp(00000) : Line up current runlevel 1 to 5; next event "check" due in 1000 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000015 i Daemon Daemon.cpp(00000) : Runlevel 1 started
...
두번째 단계는 Compileserver 와 Preprocessor 서비스이다.
daemon_<hostname>.3<Instance number>00.XXX.trc
...
### compileserver 서비스 시작
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000016 i Daemon Program.cpp(00000) : Update runlevel of program 'compileserver', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000017 i Daemon Program.cpp(00000) : Instance 0 of program 'compileserver' will be started in 0 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000018 i Daemon Program.cpp(00000) : Starting instance right now
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000019 i Daemon DaemonChild.cpp(00000) : Starting program 'hdbcompileserver' with args ''
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000020 i Daemon DaemonChild.cpp(00000) : Child program 'hdbcompileserver', pid 00000 started in its own process group
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000021 i Daemon RunningInstance.cpp(00000) : Start 'hdbcompileserver' as process 00000, process group 00000, instance 0 of <HDB Compileserver>
...
### preprocessor 서비스 시작
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000022 i Daemon Program.cpp(00000) : Update runlevel of program 'preprocessor', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000023 i Daemon Program.cpp(00000) : Instance 0 of program 'preprocessor' will be started in 0 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000024 i Daemon Program.cpp(00000) : Starting instance right now
[42521]{-1}[-1/-1] 2020-12-15 17:30:19.243871 i Daemon DaemonChild.cpp(00000) : Starting program 'hdbpreprocessor' with args ''
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000025 i Daemon DaemonChild.cpp(00000) : Child program 'hdbpreprocessor', pid 00000 started in its own process group
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000026 i Daemon RunningInstance.cpp(00000) : Start 'hdbpreprocessor' as process 00000, process group 00000, instance 0 of <HDB Preprocessor>
...
### compileserver, preprocessor 서비스 시작 중...
...
### 내부 소켓통신으로 compileserver 상태 체크 -> Return msg "started"
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000027 i Daemon NetworkListener.cpp(00000) : New connection accepted from 127.0.0.1/00000_tcp over socket 13
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000028 i Daemon NetworkConnection.cpp(00000) : Connection from 127.0.0.1/00000_tcp socket 13 pid 00000 'hdbcompileserver'. Received message "started"
### compileserver 서비스 시작완료
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000029 i Daemon DaemonHandle.cpp(00000) : Program 'hdbcompileserver', pid 00000 is started
### 내부 소켓통신으로 preprocessor 상태 체크 -> Return msg "started"
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000030 i Daemon NetworkListener.cpp(00000) : New connection accepted from 127.0.0.1/00000_tcp over socket 13
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000031 i Daemon NetworkConnection.cpp(00000) : Connection from 127.0.0.1/00000_tcp socket 13 pid 00000 'hdbpreprocessor'. Received message "started"
### preprocessor 서비스 시작완료
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000032 i Daemon DaemonHandle.cpp(00000) : Program 'hdbpreprocessor', pid 00000 is started
...
### Runlevel 수정 (1->2)
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000033 i Daemon DaemonHandle.cpp(00000) : Last instance in runlevel 2 started
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000034 i Daemon Program.cpp(00000) : Update runlevel of program 'nameserver', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000035 i Daemon Program.cpp(00000) : Update runlevel of program 'compileserver', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000036 i Daemon Program.cpp(00000) : Update runlevel of program 'preprocessor', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000037 i Daemon Daemon.cpp(00000) : Line up current runlevel 2 to 5; next event "check" due in 1000 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000038 i Daemon Daemon.cpp(00000) : Runlevel 2 started
...
세번째 단계는 Indexserver 와 Xsengine 서비스이다.
daemon_<hostname>.3<Instance number>00.XXX.trc
...
### indexserver 서비스 시작 (각 Tenant DB 별)
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000039 i Daemon Program.cpp(00000) : Update runlevel of program 'indexserver.<TENANTDB>', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000040 i Daemon Program.cpp(00000) : Instance X of program 'indexserver.<TENANTDB>' will be started in 0 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000041 i Daemon Program.cpp(00000) : Starting instance right now
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000042 i Daemon DaemonChild.cpp(00000) : Starting program 'hdbindexserver' with args '-port <TENANTDB_internal_port>'
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000043 i Daemon DaemonChild.cpp(00000) : Child program 'hdbindexserver', pid 00000 started in its own process group
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000044 i Daemon RunningInstance.cpp(00000) : Start 'hdbindexserver -port <TENANTDB_internal_port>' as process 00000, process group 00000, instance X of <HDB Indexserver-<TENANTDB>>
### xsengine 서비스 시작 (각 Tenant DB 별)
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000045 i Daemon Program.cpp(00000) : Update runlevel of program 'xsengine.<TENANTDB>', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000046 i Daemon Program.cpp(00000) : Instance X of program 'xsengine.<TENANTDB>' will be started in 0 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000047 i Daemon Program.cpp(00000) : Starting instance right now
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000048 i Daemon DaemonChild.cpp(00000) : Starting program 'hdbxsengine' with args '-port <TENANTDB_xsengine_port>'
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000049 i Daemon DaemonChild.cpp(00000) : Child program 'hdbxsengine', pid 00000 started in its own process group
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000050 i Daemon RunningInstance.cpp(00000) : Start 'hdbxsengine -port <TENANTDB_xsengine_port>' as process 00000, process group 00000, instance X of <HDB XSEngine-<TENANTDB>>
...
### indexserver, xsengine 서비스 시작 중...
...
### 내부 소켓통신으로 indexserver 상태 체크 -> Return msg "started"
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000051 i Daemon NetworkListener.cpp(00000) : New connection accepted from 127.0.0.1/00000_tcp over socket 13
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000052 i Daemon NetworkConnection.cpp(00000) : Connection from 127.0.0.1/00000_tcp socket 13 pid 00000 'hdbindexserver'. Received message "started"
### indexserver 서비스 시작완료
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000053 i Daemon DaemonHandle.cpp(00000) : Program 'hdbindexserver', pid 00000 is started
### 내부 소켓통신으로 xsengine 상태 체크 -> Return msg "started"
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000054 i Daemon NetworkListener.cpp(00000) : New connection accepted from 127.0.0.1/00000_tcp over socket 13
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000055 i Daemon NetworkConnection.cpp(00000) : Connection from 127.0.0.1/00000_tcp socket 13 pid 00000 'hdbxsengine'. Received message "started"
### xsengine 서비스 시작완료
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000056 i Daemon DaemonHandle.cpp(00000) : Program 'hdbxsengine', pid 00000 is started
...
### Runlevel 수정 (2->3)
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000057 i Daemon DaemonHandle.cpp(00000) : Last instance in runlevel 3 started
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000058 i Daemon Program.cpp(00000) : Update runlevel of program 'nameserver', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000059 i Daemon Program.cpp(00000) : Update runlevel of program 'compileserver', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000060 i Daemon Program.cpp(00000) : Update runlevel of program 'preprocessor', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000061 i Daemon Program.cpp(00000) : Update runlevel of program 'indexserver.<TENANTDB>', instance X
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000062 i Daemon Program.cpp(00000) : Update runlevel of program 'xsengine.<TENANTDB>', instance X
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000063 i Daemon Daemon.cpp(00000) : Line up current runlevel 3 to 5; next event "check" due in 1000 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000064 i Daemon Daemon.cpp(00000) : Runlevel 3 started
...
네번째 단계는 webdispatcher 서비스이다.
daemon_<hostname>.3<Instance number>00.XXX.trc
...
### webdispathcer 서비스 시작
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000065 i Daemon Program.cpp(00000) : Update runlevel of program 'webdispatcher', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000066 i Daemon Program.cpp(00000) : Instance 0 of program 'webdispatcher' will be started in 0 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000067 i Daemon Program.cpp(00000) : Starting instance right now
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000068 i Daemon DaemonChild.cpp(00000) : Starting program 'hdbwebdispatcher' with args ''
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000069 i Daemon DaemonChild.cpp(00000) : Child program 'hdbwebdispatcher', pid 00000 started in its own process group
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000070 i Daemon RunningInstance.cpp(00000) : Start 'hdbwebdispatcher' as process 00000, process group 00000, instance 0 of <HDB Web Dispatcher>
...
### webdispatcher 서비스 시작 중...
...
### 내부 소켓통신으로 webdispatcher 상태 체크 -> Return msg "started"
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000071 i Daemon NetworkListener.cpp(00000) : New connection accepted from 127.0.0.1/00000_tcp over socket 13
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000072 i Daemon NetworkConnection.cpp(00000) : Connection from 127.0.0.1/00000_tcp socket 13 pid 00000 'hdbwebdispatcher'. Received message "started"
### webdispatcher 서비스 시작완료
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000073 i Daemon DaemonHandle.cpp(00000) : Program 'hdbwebdispatcher', pid 00000 is started
### Runlevel 수정 (3->4)
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000074 i Daemon DaemonHandle.cpp(00000) : Last instance in runlevel 4 started
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000075 i Daemon Program.cpp(00000) : Update runlevel of program 'nameserver', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000076 i Daemon Program.cpp(00000) : Update runlevel of program 'compileserver', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000077 i Daemon Program.cpp(00000) : Update runlevel of program 'preprocessor', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000078 i Daemon Program.cpp(00000) : Update runlevel of program 'indexserver.<TENANTDB>', instance X
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000079 i Daemon Program.cpp(00000) : Update runlevel of program 'xsengine.<TENANTDB>', instance X
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000080 i Daemon Program.cpp(00000) : Update runlevel of program 'webdispatcher', instance 0
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000081 i Daemon Daemon.cpp(00000) : Line up current runlevel 4 to 5; next event "check" due in 1000 ms
[00000]{-0}[-0/-0] 2000-01-01 00:00:00.000082 i Daemon Daemon.cpp(00000) : Runlevel 4 started
...
다섯번째 단계는 지금까지 시작한 서비스들을 다시 한번 체크한다.
daemon_<hostname>.3<Instance number>00.XXX.trc
...
### Runlevel 5 시작
[42521]{-1}[-1/-1] 2020-12-15 17:30:51.926495 i Daemon Daemon.cpp(00000) : Runlevel 5 started
### 서비스 전체 체크
[42521]{-1}[-1/-1] 2020-12-15 17:30:51.926496 i Daemon Daemon.cpp(00000) : Target runlevel lined up
### Runlevel 5 완료
[42521]{-1}[-1/-1] 2020-12-15 17:30:51.926497 i Daemon Daemon.cpp(00000) : Runlevel 5 is completed
...