วันศุกร์ที่ 27 เมษายน พ.ศ. 2561

Monitor Exadata ด้วย ExaWatcher (GetExaWatcherResults.sh)

ถ้าระบบ Exadata เกิดปัญหาเรื่อง performance เรามีหลายวิธีที่จะ Monitor มันได้และ ExaWatcher เป็นอีก tool นึงที่ช่วย Monitor Exadata ในบทความนี้จะใช้ GetExaWatcherResults.sh script (based on ExaWatcher) ในการเก็บข้อมูลต่างๆออกมาเป็น html ไฟล์เพื่อดูผ่าน Web Browser ได้
GetExaWatcherResults.sh จะได้ข้อมูลเกี่ยวกับ
     - CPU utilization and details
     - IO Summary
     - อื่นๆ

Example:
1. As root, cd /opt/oracle.ExaWatcher



2. Execute สคริปต์เลือกเวลา --from ...  --to ...   --resultdir  </พาธที่เก็บไฟล์ผลลัพท์>



3. สคริปต์จะเก็บข้อมูลต่างๆและ Generate ไฟล์ให้และวางไฟล์ไว้ที่พาธตามพารามิเตอร์ --resultdir ที่เราส่งค่าไป



4. สามารถโหลดไฟล์มา Extract บนเครื่องเราแล้วเข้าโฟลเดอร์ Charts เพื่อดูไฟล์ html ได้เลย


5. เปิดไฟล์ index.html


6. ตัวอย่าง











วันเสาร์ที่ 3 มีนาคม พ.ศ. 2561

ปรับ SQL*PLUS prompt ไปที่ username ที่ใช้ connect

ไปแก้ไขไฟล์ config ที่ ORACLE_HOME/sqlplus/glogin.sql


--
-- Copyright (c) 1988, 2005, Oracle.  All Rights Reserved.
--
-- NAME
--   glogin.sql
--
-- DESCRIPTION
--   SQL*Plus global login "site profile" file
--
--   Add any SQL*Plus commands here that are to be executed when a
--   user starts SQL*Plus, or uses the SQL*Plus CONNECT command.
--
-- USAGE
--   This script is automatically run
--
SET SQLPROMPT "_USER'@'_CONNECT_IDENTIFIER _DATE> " -- Write this



วันพุธที่ 17 มกราคม พ.ศ. 2561

Create Oracle Active Data Guard step by step

ในการสร้าง Active Data Guard เราต้องมี Physical Standby Database ก่อนแล้วถึง enable Active Data Guard ได้

Preparation:
ตัวอย่างของบทความนี้เซ็ต Primary Database บน Linux ด้วย parameter ตามด้านล่าง
db_unique_name='linux_un'
db_name='orcl'
เซ็ต Standby Database บน Windows ด้วย parameter ตามด้านล่าง
db_unique_name='windows_un'
db_name='orcl'

1. Install Oracle Database software ที่เครื่อง Standby (ต้องเป็น Version เดียวกันและ EE)
2. Primary Database ต้องเป็น archive log mode
3. Primary Database เป็น force logging mode (SQL> alter database force logging;)

4. สร้าง standby redo log ที่ Primary Database ให้จำนวน size เท่ากับ online redo log และมี group มากกว่า 1 group ถ้าเป็น RAC ก็สร้างเพิ่มอีกเป็น n+1 สำหรับแต่ละ thread

Implementation:
1. เนื่องจากเครื่อง Standby เป็น Windows จึงต้องสร้าง Windows service  
oradim -NEW -SID windows -STARTMODE manual -PFILE C:\app\KITTI-SRS\product\11.2.0\dbhome_1\database\init.ora

2. ตัวอย่าง Initialization parameters ของทั้ง Primary และ Standby จะมีที่สำคัญคือ
LOCAL_LISTENER , FAL_SERVER , LOG_ARCHIVE_DEST_1 , LOG_ARCHIVE_DEST_2 , DB_UNIQUE_NAME , INSTANCE_NAME , STANDBY_FILE_MANAGEMENT , DB_FILE_NAME_CONVERT , LOG_FILE_NAME_CONVERT)

Primary Database
*.audit_file_dest='/u01/app/oracle/admin/orcl/adump'
*.audit_trail='db'
*.compatible='11.2.0.4.0'
*.control_files='/u01/app/oracle/oradata/orcl/control01.ctl','/u01/app/oracle/fast_recovery_area/orcl/control02.ctl'
*.db_block_size=8192
*.db_unique_name='linux_un'
*.db_domain=''
*.db_name='orcl'
*.instance_name='linux'
*.local_listener='LISTENER'
*.fal_server='windows' # for switchover purpose
*.log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES)'
*.log_archive_dest_2='SERVICE=windows LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=windows_un'
*.log_archive_config='DG_CONFIG=(linux_un,windows_un)'
*.log_archive_max_processes=8
*.db_file_name_convert='C:\app\KITTI-SRS\oradata\orcl','/u01/app/oracle/oradata/orcl' # for switchover purpose
*.log_file_name_convert='C:\app\KITTI-SRS\oradata\orcl','/u01/app/oracle/oradata/orcl' # for switchover purpose
*.standby_file_management='AUTO' # for switchover purpose
*.db_recovery_file_dest='/u01/app/oracle/fast_recovery_area'
*.db_recovery_file_dest_size=4385144832
*.diagnostic_dest='/u01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.log_archive_format='%t_%s_%r.dbf'
*.memory_target=1153433600
*.open_cursors=300
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.undo_tablespace='UNDOTBS1'

Standby Database
*.audit_file_dest='C:\app\KITTI-SRS\admin\orcl\adump'
*.audit_trail='db'
*.compatible='11.2.0.4.0'
*.control_files='C:\app\KITTI-SRS\oradata\orcl\control01.ctl','C:\app\KITTI-SRS\fast_recovery_area\orcl\control02.ctl'
*.db_block_size=8192
*.db_unique_name='windows_un'
*.db_domain=''
*.db_name='orcl'
*.instance_name='windows'
*.fal_server='linux' # for switchover purpose
local_listener='LISTENER'
*.log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES)'
*.log_archive_dest_2='SERVICE=linux LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=linux_un' # for switchover purpose
*.log_archive_config='DG_CONFIG=(linux_un,windows_un)'
*.log_archive_max_processes=8
*.log_file_name_convert='/u01/app/oracle/oradata/orcl','C:\app\KITTI-SRS\oradata\orcl' # for switchover purpose
*.db_file_name_convert='/u01/app/oracle/oradata/orcl','C:\app\KITTI-SRS\oradata\orcl' # for switchover purpose
*.standby_file_management='AUTO'
*.db_recovery_file_dest='C:\app\KITTI-SRS\fast_recovery_area'
*.db_recovery_file_dest_size=4385144832
*.diagnostic_dest='C:\app\KITTI-SRS'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.log_archive_format='%t_%s_%r.dbf'
*.memory_target=1153433600
*.open_cursors=300
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'

*.undo_tablespace='UNDOTBS1'


Note. db_file_name_convert กับ log_file_name_convert เป็น static parameter ซึ่งต้อง restart database

3. ตั้งค่า Listener เพื่อ enable static service registration เพื่อใช้ในการทำ RMAN duplicate database แบบ active

Primary 
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = kittisource)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )
SID_LIST_LISTENER =
 (SID_LIST =
 (SID_DESC =
 (SID_NAME = PLSExtProc)
 (ORACLE_HOME = /u01/app/oracle/product/11.2.0.4/dbhome_1)
 (PROGRAM = extproc))
 (SID_DESC =
 (GLOBAL_DBNAME = linux_un)
 (SID_NAME = linux)
 (ORACLE_HOME = /u01/app/oracle/product/11.2.0.4/dbhome_1)))


ADR_BASE_LISTENER = /u01/app/oracle

Standby
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = KITTISRS)(PORT = 1521))
    )
  )
SID_LIST_LISTENER =
 (SID_LIST =
 (SID_DESC =
      (SID_NAME = CLRExtProc)
      (ORACLE_HOME = C:\app\KITTI-SRS\product\11.2.0\dbhome_1)
      (PROGRAM = extproc)
      (ENVS = "EXTPROC_DLLS=ONLY:C:\app\KITTI-SRS\product\11.2.0\dbhome_1\bin\oraclr11.dll")
    )
 (SID_DESC =
 (GLOBAL_DBNAME = windows_un)
 (SID_NAME = windows)
 (ORACLE_HOME = C:\app\KITTI-SRS\product\11.2.0\dbhome_1)))

ADR_BASE_LISTENER = C:\app\KITTI-SRS

4. เพิ่ม TNS alias ใน tnsnames.ora เพื่อให้ Primary กับ Standby สามารถ connect ผ่าน TNS alias ได้
(เพิ่ม alias ให้ LISTENER ด้วยเพราะใช้ใน LOCAL_LISTENER parameter)

Primary and Standby
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = KITTISRS)(PORT = 1521))
    )
  )

linux =
 (DESCRIPTION =
 (ADDRESS = (PROTOCOL = TCP)(HOST = kittisource)(PORT = 1521))
 (CONNECT_DATA =
 (SERVER = DEDICATED)
 (SERVICE_NAME = linux_un)))

windows =
 (DESCRIPTION =
 (ADDRESS = (PROTOCOL = TCP)(HOST = KITTISRS)(PORT = 1521))
 (CONNECT_DATA =
 (SERVER = DEDICATED)
 (SERVICE_NAME = windows_un)))

5. ทำการ copy password file จาก Primary ไปที่ Standby แล้วเปลี่ยนชื่อเป็น pwd<sid>.ora
6. เปิด Standby Database เป็น nomount mode และ start listener (ใช้ parameter file ที่เตรียมไว้และควรสร้างและใช้ spfile แทน)



7. เช็คสถานะของ Primary Database (ต้องเป็น open หรือ mount เพื่อทำ RMAN active duplicate)

8. ใช้ RMAN (ที่เครื่อง Primary หรือ Standby ก็ได้) เพื่อ connect ทั้ง Primary และ Standby

9. ใช้คำสั่ง RMAN duplicate เพื่อทำการคัดลอกไฟล์จาก Primary Database เพื่อไปสร้าง Standby Database

Verification:
1. Query จากเครื่อง Standby Database เพื่อตรวจสอบข้อมูลของ DB

2. เช็ค data files


3. เช็ค online redo log files กับ standby redo log files

4. ตรวจสอบว่า redo transport service ทำงานอยู่ไหม (RFS processes running)


Start and Test Active Data Guard:
1. Open database และเปิด Real-time apply

2. ทดลองสร้าง table และ query

วันอังคารที่ 31 ตุลาคม พ.ศ. 2560

Install Oracle Database on Docker Container

Software ที่ใช้คือ Oracle Database 12cR2 (12.2.0.1) บน Oracle Linux 7 และ Docker Image ที่มี default database ใน multi-tenant configuration with a single pluggable database
ตรวจเช็ค OS kernel และ ติดตั้ง Docker



Disable SELinux

Enable the ol7_addons และ ol7_UEKR4 เพื่อโหลด docker จาก yum repository นี้
#vi /etc/yum.repos.d/public-yum-ol7.repo
ติดตั้ง docker-engine และตรวจสอบ version
# yum install docker-engine
# docker --version

Prepare for install Oracle Database

ติดตั้ง oracle-database-server-12cR2-preinstall package เพื่อเซ็ตอัพ environment ที่จำเป็นและ required package ต่างๆ

เพิ่มพื้นที่ storage ให้กับ docker container เป็น 30GB (จากเดิม 25GB)
#vi /etc/sysconfig/docker-storage



อนุญาตให้ oracle user สามารถใช้ sudo และรัน docker commands ต้องเพิ่ม oracle user ไปที่ /etc/sudoers file.
หรือรัน visudo
#visudo

Switch user ไปเป็น oracle (su – oracle) และ download Oracle image files และ database zip file

[oracle@kitti-srs ~]$ wget https://github.com/oracle/docker-images/archive/master.zip
[oracle@kitti-srs ~]$ unzip master.zip
[oracle@kitti-srs ~]$ cd docker-images-master/OracleDatabase/dockerfiles/12.2.0.1/
Copy oracle 12cR2 database software ไปที่พาธ docker-images-master/OracleDatabase/dockerfiles/12.2.0.1/
สร้าง Docker image
ไปที่พาธ docker-images-master/OracleDatabase/dockerfiles
$sudo ./buildDockerImage.sh -v 12.2.0.1 -e


ตอนนี้พร้อมที่จะสร้าง Oracle Database ใน Docker Container แล้ว
สร้าง container ด้วยคำสั่ง
$ sudo docker run -p 1521:1521 –name kitti-container oracle/database:12.2.0.1-ee
ทดลอง Start , Stop , and List Docker Container
$ sudo docker stop kitti-container
$ sudo docker start kitti-container
$ sudo docker ps



Starting an Active Terminal and connect to SQL * Plus
$ sudo docker exec -it <container_name> bash


ทดลองสร้าง database เพิ่มอีก 1 ตัว ด้วย DBCA silent mode


วันจันทร์ที่ 24 สิงหาคม พ.ศ. 2558

How to change public ip , vip , scan

เปลี่ยน Public IP ก่อน
1. ปิด database และ nodeapps
srvctl stop database -d dbname
srvctl stop nodeapps -n node1
srvctl stop nodeapps -n node2

2. เปลี่ยน Public Interface
oifcfg getif
eth0  192.168.16.0  global  cluster_interconnect,asm
eth1  172.16.4.0  global  public
oifcfg delif -global eth1
oifcfg setif -global eth1/172.16.21.0:public

เช็คอีกที
oifcfg getif
eth0  192.168.16.0  global  cluster_interconnect,asm
eth1  172.16.21.0  global  public

* แก้อีก node นึงด้วย

3. แก้ไข VIP Interface
srvctl modify nodeapps -n node1 -A 172.16.21.107/255.255.255.0/eth1
srvctl modify nodeapps -n node2 -A 172.16.21.108/255.255.255.0/eth1

* ถ้าแก้ไม่ได้ให้แก้ network ก่อนเพราะอาจใช้ subnet คนละวง

4. Stop CRS ทั้ง 2 nodes
crsctl stop crs

5. แก้ไข IP Address ที่ OS (/etc/hosts ด้วยก็ได้)
vi /etc/sysconfig/network-scripts/ifcfg-eth1

6. Reboot all nodes
7. หลังจาก reboot แล้ว database ควรจะ start ขึ้นมาได้ปกติ เราสามารถใช้คำสั่งเช็คได้เช่น
crsctl stat res -t
srvctl status database -d dbname
srvctl status listener

8. แก้ไข scan
srvctl stop scan
srvctl stop scan_listener
srvctl modify scan
srvctl start scan
srvctl start scan_listener

* มันจะปรับค่าให้โดยอ่านจาก VIP ให้เอง

เราสามารถเช็คค่าใหม่ได้ด้วย
srvctl config scan



วันอังคารที่ 11 สิงหาคม พ.ศ. 2558

วิธีสร้าง TAF session failover แบบ SELECT โดยใช้ server side service

สมมุติว่าเราพึ่งสร้าง RAC database ขึ้นมาใหม่และเราอยากให้ขณะ SELECT อยู่แล้วหาก Current instance หลุดไป Session ของเราจะไป SELECT ต่อที่อีก Instance นึงเราต้องสร้าง Service ขึ้นมาเป็นแบบ SELECT type

ตัวอย่าง
1. สร้าง service ขึ้นมา 1 ตัวชื่อ TAF เป็นแบบ SELECT type
srvctl add service -d cubprod -s TAF -r "cubprod1,cubprod2" -e SELECT -m BASIC -P BASIC -z 5 -w 10

2. ตรวจสอบ config service ของเรา
srvctl config service -d cubprod -s TAF
Service name: TAF
Service is enabled
Server pool: cubprod_TAF
Cardinality: 2
Disconnect: false
Service role: PRIMARY
Management policy: AUTOMATIC
DTP transaction: false
AQ HA notifications: false
Failover type: SELECT
Failover method: BASIC
TAF failover retries: 5
TAF failover delay: 10
Connection Load Balancing Goal: LONG
Runtime Load Balancing Goal: NONE
TAF policy specification: BASIC
Edition: 
Preferred instances: cubprod1,cubprod2
Available instances:

3. Start the service
srvctl start service -d cubprod -s TAF
4. ลองเช็คด้วย lsnrctl status จะมี TAF service ขึ้นมาทั้ง 2 node

5. ทดลองใช้งานโดยเข้า Service TAF แล้วขณะ SELECT อยู่ให้ลอง kill -9 pmon ของ current instance ดูจะพบว่า Session ได้ถูกย้ายไปอีก Instance นึงโดยอัตโนมัติ
สามารถเช็คได้ด้วย Query
select host_name,instance_name from v$instance;


ปล. ถ้าเป็น SYS user จะขึ้น ORA-03113: end-of-file on communication channel ทีนึงก่อนแล้วมันจะไป connect ใหม่ให้ แต่ถ้าเป็น user ธรรมดามันจะย้ายไปให้เลย

วันจันทร์ที่ 22 มิถุนายน พ.ศ. 2558

Query from multiple rows to single line

ฟังก์ชั่น LISTAGG() เป็นฟังก์ชั่นใหม่ในเวอร์ชั่น 11GR2 เพื่อเชื่อม multiple rows ให้เป็น single line

รูปแบบ syntax
LISTAGG( [,]) WITHIN GROUP (ORDER BY ) [OVER (PARTITION BY )]

ปล. สามารถใช้ในการ Analytic ได้เช่นใช้คำสั่ง OVER() clause

ตัวอย่างนี้จะดู username ใน dba_users โดยจะให้มันเชื่อมต่อกันเป็นบรรทัดเดียวและคั่นด้วยเครื่องหมาย ","