페이지 이력
...
패치 파일을 다운로드 받아 압축을 해제하면 파일 안에 README.html 파일이 존재합니다.
해당 파일에는 패치 방법이나 주의 사항과 관련된 자세한 안내가 기록되어 있습니다.
...
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
export ORACLE_BASE=/u01/app/oracle
export GRID_HOME=/u01/app/12.1.0/grid
export DB_HOME=$ORACLE_BASE/product/12.1.0/db_1
# mkdir -p /u01/app/oracle/cfgtoollogs/sqlpatch/26925263/21857460
# chown -R grid:oinstall /u01/app/oracle/cfgtoollogs/sqlpatch
# chmod -R 775 /u01/app/oracle/cfgtoollogs |
펼치기 | ||
---|---|---|
|
...
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
cd $GRID_HOME OPatch/opatch version mv OPatch OPatch.oldbak cp -r /media/sf_oracle <압축 해제 경로>/OPatch . chown -R grid:oinstall OPatch ll | grep OPatch OPatch/opatch version |
펼치기 | ||||
---|---|---|---|---|
|
...
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
cd $DB_HOME OPatch/opatch version mv OPatch OPatch.oldbak cp -r /media/sf_oracle <압축 해제 경로>/OPatch . chown -R oracle:oinstall OPatch ll | grep OPatch OPatch/opatch version |
펼치기 | ||||
---|---|---|---|---|
|
...
펼치기 | ||||
---|---|---|---|---|
|
GRID 패치 충돌 여부 검증
grid 유저로 1번과 2번 노드에 접속하여 양쪽에서 모두 실행합니다.
pass되지 않은 항목이 있다면 oracle에 기술 지원을 요청해야 합니다. (기존 패치의 rollback 등의 작업이 필요할 수 있으므로 반드시 가이드를 받고 진행합니다.)
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$GRID_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /media/sf_oracle/27010930/26925263
$GRID_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /media/sf_oracle/27010930/26925218
$GRID_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /media/sf_oracle/27010930/26910974
$GRID_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /media/sf_oracle/27010930/26983807 |
펼치기 | ||||
---|---|---|---|---|
|
GRID 패치 디스크 용량 확인
GRID 패치를 위해 충분한 디스크 용량이 확보되어 있는지 검사합니다.
적용할 패치 파일의 디렉토리 경로를 텍스트 파일에 저장하고, opatch의 CheckSystemSpace 옵션을 이용하여 디스크 공간을 검사합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
vi /tmp/patch_list_gihome.txt
# cat /tmp/patch_list_gihome.txt
$GRID_HOME/OPatch/opatch prereq CheckSystemSpace -phBaseFile /tmp/patch_list_gihome.txt |
펼치기 | ||
---|---|---|
|
Database의 패치 내역 확인
oracle 유저로 1번과 2번 노드에 접속하여 양쪽에서 모두 실행합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$DB_HOME/OPatch/opatch lsinventory |
펼치기 | ||||
---|---|---|---|---|
|
Database 패치 충돌 여부 검증
oracle 유저로 1번과 2번 노드에 접속하여 양쪽에서 모두 실행합니다.
pass되지 않은 항목이 있다면 oracle에 기술 지원을 요청해야 합니다. (경우에 따라 기존 패치의 rollback 등의 작업이 필요할 수 있으므로 반드시 가이드를 받고 진행합니다.)
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$DB_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /media/sf_oracle/27010930/26925263
$DB_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /media/sf_oracle/27010930/26925218 |
펼치기 | ||||
---|---|---|---|---|
|
Database 패치 디스크 용량 확인
Database 패치를 위해 충분한 디스크 용량이 확보되어 있는지 검사합니다.
적용할 패치 파일의 디렉토리 경로를 텍스트 파일에 저장하고, opatch의 CheckSystemSpace 옵션을 이용하여 디스크 공간을 검사합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
vi /tmp/patch_list_dbhome.txt
# cat /tmp/patch_list_dbhome.txt
$DB_HOME/OPatch/opatch prereq CheckSystemSpace -phBaseFile /tmp/patch_list_dbhome.txt |
펼치기 | ||
---|---|---|
|
Grid 및 DBMS 패치 적용
opatchauto 수행하기
root 유저로 실행하며, 한 노드의 작업이 모두 완료된 후에 다른 노드에 작업을 수행합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
opatchauto apply /media/sf_oracle/27010930 |
펼치기 | ||||
---|---|---|---|---|
1번 노드에서 실패 메시지가 발생할 수 있으나, 무시하고 2번 노드에 패치를 적용합니다.
|
MGMTDB 패치 적용하기
sqlpatch 로그 디렉토리 권한 변경
추후 datapatch를 정상적으로 진행하기 위해서는 sqlpatch 로그 디렉토리의 권한을 수정해야 합니다.
datapatch를 실행할 노드의 디렉토리만 적용해도 됩니다.
만약 grid와 database가 같은 유저로 설치되어 있다면, 이 작업은 생략해도 됩니다.
코드 블럭 |
---|
chmod -R 775 /u01/app/oracle/cfgtoollogs/sqlpatch |
펼치기 | ||
---|---|---|
|
MGMTDB 상태 확인
grid 유저로 접속해서 MGMTDB에 연결합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
export ORACLE_SID=-MGMTDB
sqlplus / as sysdba |
펼치기 | ||
---|---|---|
|
정상적으로 연결이 되었으며, 기존에 패치 내역이 있는지 확인합니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
SELECT instance_name FROM v$instance;
select PATCH_ID, VERSION, ACTION, STATUS, ACTION_TIME from DBA_REGISTRY_SQLPATCH; |
펼치기 | ||
---|---|---|
WITH ERRORS 상태인 것으로 보아 datapatch가 제대로 적용되지 않은 것을 확인할 수 있습니다.
|
MGMTDB에 datapatch 적용하기
grid 유저에서 MGMTDB에 대한 datapatch를 적용합니다.
반드시 ORACLE_SID가 -MGMTDB로 지정된 상태에서 수행해야 합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
cd $ORACLE_HOME/OPatch
./datapatch -verbose |
펼치기 | ||
---|---|---|
|
MGMTDB 패치 결과 확인
MGMTDB에 접속하여 제대로 datapatch가 적용되었는지 확인합니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
SELECT patch_id, version, action, status, action_time FROM dba_registry_sqlpatch; |
펼치기 | ||
---|---|---|
|
Database 패치 적용하기
PDB 상태 확인 및 변경
패치를 적용할 PDB의 상태를 모두 READ WRITE 모드로 변경해 줍니다.
만약 Multitenent Database가 아닌 경우에는 Database를 Open 시켜 주면 됩니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
SELECT name, open_mode FROM v$pdbs;
ALTER PLUGGABLE DATABASE ALL OPEN;
SELECT name, open_mode FROM v$pdbs; |
펼치기 | ||
---|---|---|
|
Database에 datapatch 적용하기
oracle 유저로 database에 대한 datapatch를 적용합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
cd $ORACLE_HOME/OPatch
./datapatch -verbose |
펼치기 | ||
---|---|---|
|
Database 패치 결과 확인
패치가 정상적으로 적용되었는지 확인합니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
SELECT patch_id, version, action, status, action_time FROM dba_registry_sqlpatch; |
|
GRID 패치 충돌 여부 검증
grid 유저로 1번과 2번 노드에 접속하여 양쪽에서 모두 실행합니다.
pass되지 않은 항목이 있다면 oracle에 기술 지원을 요청해야 합니다. (기존 패치의 rollback 등의 작업이 필요할 수 있으므로 반드시 가이드를 받고 진행합니다.)
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$GRID_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir <패치 압축 해제 경로>/27010930/26925263
$GRID_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir <패치 압축 해제 경로>/27010930/26925218
$GRID_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir <패치 압축 해제 경로>/27010930/26910974
$GRID_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir <패치 압축 해제 경로>/27010930/26983807 |
펼치기 | ||||
---|---|---|---|---|
|
GRID 패치 디스크 용량 확인
GRID 패치를 위해 충분한 디스크 용량이 확보되어 있는지 검사합니다.
적용할 패치 파일의 디렉토리 경로를 텍스트 파일에 저장하고, opatch의 CheckSystemSpace 옵션을 이용하여 디스크 공간을 검사합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
vi /tmp/patch_list_gihome.txt
# cat /tmp/patch_list_gihome.txt
$GRID_HOME/OPatch/opatch prereq CheckSystemSpace -phBaseFile /tmp/patch_list_gihome.txt |
펼치기 | ||||
---|---|---|---|---|
|
Database의 패치 내역 확인
oracle 유저로 1번과 2번 노드에 접속하여 양쪽에서 모두 실행합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$DB_HOME/OPatch/opatch lsinventory |
펼치기 | ||||
---|---|---|---|---|
|
Database 패치 충돌 여부 검증
oracle 유저로 1번과 2번 노드에 접속하여 양쪽에서 모두 실행합니다.
pass되지 않은 항목이 있다면 oracle에 기술 지원을 요청해야 합니다. (기존 패치의 rollback 등의 작업이 필요할 수 있으므로 반드시 가이드를 받고 진행합니다.)
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$DB_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir <패치 압축 해제 경로>/27010930/26925263
$DB_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir <패치 압축 해제 경로>/27010930/26925218 |
펼치기 | ||||
---|---|---|---|---|
|
Database 패치 디스크 용량 확인
Database 패치를 위해 충분한 디스크 용량이 확보되어 있는지 검사합니다.
적용할 패치 파일의 디렉토리 경로를 텍스트 파일에 저장하고, opatch의 CheckSystemSpace 옵션을 이용하여 디스크 공간을 검사합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
vi /tmp/patch_list_dbhome.txt
# cat /tmp/patch_list_dbhome.txt
$DB_HOME/OPatch/opatch prereq CheckSystemSpace -phBaseFile /tmp/patch_list_dbhome.txt |
펼치기 | ||||
---|---|---|---|---|
|
자동 패치 : 동시에 Grid 및 DBMS 패치 적용
자동 패치를 수행할 경우 opatchauto 툴을 통해 grid와 database를 동시에 패치할 수 있습니다.
패치 방법은 간단하지만, 패치 과정 중 이슈가 발생하였을 때 분석하기 까다롭습니다.
자동 또는 수동 패치 중에 한가지 방식을 선택하여 패치를 진행하기 바랍니다.
패치 사전 검증
패치를 적용하기 전에 사전 검증하는 단계입니다.
기존 패치와의 충돌 여부와 함께 진행되는 다른 작업들에 이상이 있는지를 사전에 검증합니다.
운영기 적용시에는 가급적 패치를 적용하기 전에 검증을 수행하고 진행하는 것이 좋습니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
opatchauto apply <패치 압축 해제 경로>/27010930 -analyze |
펼치기 | ||||
---|---|---|---|---|
|
opatchauto 수행하기
root 유저로 실행하며, 한 노드의 작업이 모두 완료된 후에 다른 노드에 작업을 수행합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
opatchauto apply <패치 압축 해제 경로>/27010930 |
펼치기 | ||||
---|---|---|---|---|
1번 노드에서 실패 메시지가 발생할 수 있으나, 무시하고 2번 노드에 패치를 적용합니다.
|
수동 패치 : 개별적으로 Grid와 DBMS에 적용
수동 패치를 수행할 경우 opatch 툴을 통해 grid와 database를 각각 패치하게 됩니다.
단계별로 패치를 진행하게 되므로 이슈가 발생할 경우 트러블슈팅이 덜 까다롭습니다.
자동 또는 수동 패치 중에 한가지 방식을 선택하여 패치를 진행하기 바랍니다.
1번 노드 : 패치 사전 검증
1번 노드에 패치를 적용하기 전에 패치에 대한 사전 검증을 수행합니다.
운영계에 적용하려면 반드시 사전 검증을 통해 패치가 정상 적용이 되는지 확인하고 패치를 진행해야 합니다.
먼저 Grid 패치에 대한 검증을 grid 유저에서 수행합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$GRID_HOME/OPatch/opatch apply -oh $GRID_HOME -local <패치 압축 해제 경로>/27010930/26925218 -analyze
$GRID_HOME/OPatch/opatch apply -oh $GRID_HOME -local <패치 압축 해제 경로>/27010930/26910974 -analyze
$GRID_HOME/OPatch/opatch apply -oh $GRID_HOME -local <패치 압축 해제 경로>/27010930/26983807 -analyze
$GRID_HOME/OPatch/opatch apply -oh $GRID_HOME -local <패치 압축 해제 경로>/27010930/26925263 -analyze |
펼치기 | ||
---|---|---|
|
oracle 유저로 Database에 대한 패치를 검증합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$DB_HOME/OPatch/opatch apply -oh $DB_HOME -local <패치 압축 해제 경로>/27010930/26925218 -analyze
$DB_HOME/OPatch/opatch apply -oh $DB_HOME -local <패치 압축 해제 경로>/27010930/26925263 -analyze |
펼치기 | ||
---|---|---|
|
1번 노드 : DB_HOME의 서비스 중지
1번 노드에서 DB_HOME을 통해 가동중인 서비스를 중지합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
crsctl stat res -t
srvctl stop home -o $DB_HOME -s /tmp/crs_res_stop.log -n rac1
crsctl stat res -t |
펼치기 | ||
---|---|---|
|
1번 노드 : prepatch 스크립트 실행
패치 진행에 앞서 root 유저로 rootcrs.sh 스크립트를 prepatch 모드로 실행합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$GRID_HOME/crs/install/rootcrs.sh -prepatch |
펼치기 | ||
---|---|---|
|
1번 노드 : Grid 패치
$GRID_HOME 소유자 계정(grid)로 접속해서 수동 패치를 OCW, ACFS, DBWLM, DB 순으로 수행합니다.
각 패치에 대한 디렉토리 정보는 패치 파일에 포함된 README.html 파일을 참고합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$GRID_HOME/OPatch/opatch apply -oh $GRID_HOME -local <패치 압축 해제 경로>/27010930/26925218
$GRID_HOME/OPatch/opatch apply -oh $GRID_HOME -local <패치 압축 해제 경로>/27010930/26910974
$GRID_HOME/OPatch/opatch apply -oh $GRID_HOME -local <패치 압축 해제 경로>/27010930/26983807
$GRID_HOME/OPatch/opatch apply -oh $GRID_HOME -local <패치 압축 해제 경로>/27010930/26925263 |
펼치기 | ||
---|---|---|
|
1번 노드 : Database 패치
$DB_HOME 소유자 계정(oracle)로 접속해서 OCW 패치 디렉토리 안에 있는 prepatch.sh을 먼저 수행합니다.
그리고, OCW와 DB 패치 순으로 패치를 수행합니다.
패치 완료 후 OCW 패치 디렉토리 안에 있는 postpatch.sh을 수행합니다.
각 패치에 대한 디렉토리 정보는 패치 파일에 포함된 README.html 파일을 참고합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
<패치 압축 해제 경로>/27010930/26925218/custom/scripts/prepatch.sh -dbhome $DB_HOME
$DB_HOME/OPatch/opatch apply -oh $DB_HOME -local <패치 압축 해제 경로>/27010930/26925218
$DB_HOME/OPatch/opatch apply -oh $DB_HOME -local <패치 압축 해제 경로>/27010930/26925263
<패치 압축 해제 경로>/27010930/26925218/custom/scripts/postpatch.sh -dbhome $DB_HOME |
펼치기 | ||
---|---|---|
|
1번 노드 : postpatch 스크립트 실행
패치가 모두 정상 완료되었으면 root 계정에서 rootadd_rdbms.sh와 rootcrs.sh 스크립트를 postpatch 모드로 수행합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
$GRID_HOME/rdbms/install/rootadd_rdbms.sh
$GRID_HOME/crs/install/rootcrs.sh -postpatch |
펼치기 | ||
---|---|---|
Locale 관련 문제로 MGMTDB에 대한 패치가 실패된 로그를 확인할 수 있습니다. 2번 노드를 패치하기 전에 MGMTDB에 대한 datapatch를 수동으로 하는 것을 권장합니다. |
2번 노드 패치
동일한 방식으로 패치를 진행합니다.
펼치기 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Grid 패치 사전 검증
Database 패치 사전 검증
DB_HOME 서비스 중지
prepatch 스크립트 실행
Grid 패치
Database 패치
postpatch 스크립트 실행
|
MGMTDB 패치 적용하기
1번 노드 패치 과정 중 마지막 단계에서 발생한 fail을 바로잡기 위해 수동으로 MGMTDB에 대한 패치를 적용합니다.
만약, 1번 노드 패치 중에 오류가 발생하지 않았고, MGMTDB에 패치 내역이 SUCCESS로 되어 있다면 생략 가능합니다.
해당 오류는 디렉토리에 대한 권한이 부족하거나, NLS_LANG 설정이 맞지 않아서 발생하는 것으로 보입니다. (오라클 문서 ID 2242227.1)
sqlpatch 로그 디렉토리 권한 변경
추후 datapatch를 정상적으로 진행하기 위해서는 sqlpatch 로그 디렉토리의 권한을 수정해야 합니다.
datapatch를 실행할 노드의 디렉토리만 적용해도 됩니다.
코드 블럭 |
---|
chmod -R 775 /u01/app/oracle/cfgtoollogs/sqlpatch |
펼치기 | ||
---|---|---|
|
MGMTDB 상태 확인
grid 유저로 접속해서 MGMTDB에 연결합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
export ORACLE_SID=-MGMTDB
sqlplus / as sysdba |
펼치기 | ||
---|---|---|
|
정상적으로 연결이 되었으며, 기존에 패치 내역이 있는지 확인합니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
select INSTANCE_NAME from V$INSTANCE;
select PATCH_ID, VERSION, ACTION, STATUS, ACTION_TIME from DBA_REGISTRY_SQLPATCH; |
펼치기 | ||
---|---|---|
WITH ERRORS 상태인 것으로 보아 datapatch가 제대로 적용되지 않은 것을 확인할 수 있습니다.
|
MGMTDB에 datapatch 적용하기
grid 유저에서 MGMTDB에 대한 datapatch를 적용합니다.
반드시 ORACLE_SID가 -MGMTDB로 지정된 상태에서 수행해야 합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
cd $ORACLE_HOME/OPatch
./datapatch -verbose |
펼치기 | ||
---|---|---|
|
Invalid 상태가 된 객체들에 대하여 재컴파일을 수행합니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
@?/rdbms/admin/utlrp |
펼치기 | ||
---|---|---|
|
MGMTDB 패치 결과 확인
MGMTDB에 접속하여 제대로 datapatch가 적용되었는지 확인합니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
select PATCH_ID, VERSION, ACTION, STATUS, ACTION_TIME from DBA_REGISTRY_SQLPATCH; |
펼치기 | ||
---|---|---|
|
Database 패치 적용하기
PDB 상태 확인 및 변경
패치를 적용할 PDB의 상태를 모두 READ WRITE 모드로 변경해 줍니다.
만약 Multitenent Database가 아닌 경우에는 Database를 Open 시켜 주면 됩니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
SELECT name, open_mode FROM v$pdbs;
ALTER PLUGGABLE DATABASE ALL OPEN;
SELECT name, open_mode FROM v$pdbs; |
펼치기 | ||
---|---|---|
|
Database에 datapatch 적용하기
oracle 유저로 database에 대한 datapatch를 적용합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
cd $ORACLE_HOME/OPatch
./datapatch -verbose |
펼치기 | ||
---|---|---|
|
Invalid 상태가 된 객체들에 대하여 재컴파일을 수행합니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
@?/rdmb/admin/utlrp |
펼치기 | ||
---|---|---|
|
Database 패치 결과 확인
DB에 패치가 정상적으로 적용되었는지 확인합니다.
코드 블럭 | ||||
---|---|---|---|---|
| ||||
select PATCH_ID, VERSION, ACTION, STATUS, ACTION_TIME from DBA_REGISTRY_SQLPATCH; |
펼치기 | ||
---|---|---|
|
Grid와 DBMS에 정상적으로 패치가 적용되었는지 확인합니다.
코드 블럭 | ||||||
---|---|---|---|---|---|---|
| ||||||
opatch lsinventory |
펼치기 | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
펼치기 | ||||||||
|