เราสามารถกู้ความผิดพลาดในการ drop tablespace ได้ด้วย flashback database ตามนี้
SQL> alter database flashback on;
Database altered.
SQL> alter database open;
Database altered.
SQL> create tablespace kitti_tbs datafile '/u01/app/oracle/oradata/ORACLE/kitti01.dbf' size 10m;
Tablespace created.
SQL> create table kitti_tbl (id number) tablespace kitti_tbs;
Table created.
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
471727
SQL> drop tablespace kitti_tbs including contents and datafiles;
Tablespace dropped.
SQL> shutdown immediate
SQL> startup mount
SQL> flashback database to scn 471727;
Flashback complete.
--ขั้นตอนนี้ต้องเช็ค datafile ก่อนเพราะมันจะสร้างมาให้ในชื่อแปลกๆ
SQL> select name from v$datafile;
NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/ORACLE/system01.dbf
/u01/app/oracle/oradata/ORACLE/sysaux01.dbf
/u01/app/oracle/oradata/ORACLE/undotbs01.dbf
/u01/app/oracle/oradata/ORACLE/users01.dbf
/u01/app/oracle/product/11.2.0/dbhome_1/dbs/UNNAMED00005 <---- ชื่อแปลกๆที่มันสร้างมาให้
--สร้างใหม่ไปไว้ path เดิมโดยลอกไฟล์ที่มันสร้างมาให้
SQL> alter database create datafile '/u01/app/oracle/product/11.2.0/dbhome_1/dbs/UNNAMED00005' as '/u01/app/oracle/oradata/ORACLE/kitti01.dbf';
Database altered.
--สั่งให้ datafile online
SQL> alter tablespace kitti_tbs datafile online;
Tablespace altered.
--Flashback ซ้ำเข้าไปอีกที
SQL> flashback database to scn 471727;
Flashback complete.
--เปิด database ด้วย resetlogs option
SQL> alter database open resetlogs;
Database altered.
--ลอง query ดู tablespace
SQL> select name from v$tablespace;
NAME
------------------------------
SYSTEM
SYSAUX
UNDOTBS1
TEMP
USERS
KITTI_TBS <---ได้ tablespace กลับคืนมาแล้ว
--ลอง query ดู table ของเรา
SQL> select * from kitti_tbl;
no rows selected
ได้ table กลับคืนมาแล้ว
วันจันทร์ที่ 20 เมษายน พ.ศ. 2558
วันพฤหัสบดีที่ 9 เมษายน พ.ศ. 2558
ติดตั้ง Oracle 12c RAC บน Oracle Linux 6.5 โดยใช้ VirtualBox
ในที่นี้จะสมมุติว่าได้ติดตั้ง Virtual Box และ Oracle Linux แล้ว
เตรียมความพร้อมก่อนการติดตั้ง
RAM ทั้ง 2 เครื่องรวมกันควรเท่ากับหรือมากกว่า 9 GB
Disk ทั้ง 2 ควรแบ่งให้ local เครื่องละ 30GB ขึ้นไป
Prepare Network
1.เซต Network 3 ตัว
ตัวแรกเซตเป็น NAT
4.แก้ไฟล์ /etc/hosts
127.0.0.1 localhost.localdomain localhost
# Public
192.168.172.101 kitti-rac1.localdomain kitti-rac1
192.168.172.102 kitti-rac2.localdomain kitti-rac2
# Private
172.16.172.101 kitti-rac1-priv.localdomain kitti-rac1-priv
172.16.172.102 kitti-rac2-priv.localdomain kitti-rac2-priv
# Virtual
192.168.172.103 kitti-rac1-vip.localdomain kitti-rac1-vip
192.168.172.104 kitti-rac2-vip.localdomain kitti-rac2-vip
# SCAN
192.168.172.105 kitti-scan.localdomain kitti-scan
192.168.172.106 kitti-scan.localdomain kitti-scan
192.168.172.107 kitti-scan.localdomain kitti-scan
5.ติดตั้ง dnsmasq เพื่อใช้ dns
# yum install dnsmasq
แก้ไฟล์ /etc/resolv.conf
search localdomain
nameserver 192.168.172.101
nameserver 192.168.172.102
*เพื่อป้องกัน /etc/resolv.conf ถูกเขียนทับโดย Network Manager เพราะเราเซต eth0 เป็น NAT เราจึงต้องทำการแก้ไฟล์ "/etc/sysconfig/network-scripts/ifcfg-eth0" โดยปรับ ONBOOT=no หลังจากนั้นลอง reboot เครื่อง
ลองสั่ง start service
# service dnsmasq stop
# service dnsmasq start
ลองสั่ง nslookup
# nslookup kitti-scan
Server: 192.168.172.1
Address: 192.168.172.1#53
Name: kitti-scan.localdomain
Address: 192.168.56.105
Name: kitti-scan.localdomain
Address: 192.168.56.106
Name: kitti-scan.localdomain
Address: 192.168.56.107
แก้ไฟล์ /etc/dnsmasq.conf โดยปรับ
local=/localdomain/
Prepare OS
1.แก้ไขไฟล์ "/etc/security/limits.d/90-nproc.conf" เพื่อแก้ปัญหา MOS Note [ID 1487773.1]
# แก้จาก
* soft nproc 1024
# เป็น
* - nproc 16384
2. Disable SElinux "/etc/selinux/config"
SELINUX=disabled
3.ปิดไฟวอ
service iptables stop
chkconfig iptables off
4.Disable Network Time Protocal (NTP) เพื่อเราจะได้ใช้ Oracle Cluster Time Synchronization Service (ctssd) เพื่อให้มันซิงค์วันที่และเวลาระหว่างทุกเครื่องใน RAC
service ntpd stop
chkconfig ntpd off
5.สร้าง Directories เพื่อเก็บ Software
mkdir -p /u01/app/12.1.0.2/grid
mkdir -p /u01/app/oracle/product/12.1.0.2
chown -R oracle:oinstall /u01
chmod -R 775 /u01/
6.Login user เป็น oracle แล้วใส่ใน .bash_profile
# Oracle Settings
export TMP=/tmp
export TMPDIR=$TMP
export ORACLE_HOSTNAME=kitti-rac1.localdomain
export ORACLE_UNQNAME=KITTIRAC
export ORACLE_BASE=/u01/app/oracle
export GRID_HOME=/u01/app/12.1.0.2/grid
export ORACLE_HOME=$ORACLE_BASE/product/12.1.0.2
export ORACLE_SID=KITTIRAC1
export ORACLE_TERM=xterm
export BASE_PATH=/usr/sbin:$PATH
export PATH=$ORACLE_HOME/bin:$BASE_PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
7. Reboot เครื่อง 1 ทีพอเสร็จแล้วให้กด Devices > Install Guest Additions CD image...
8.เพิ่ม user oracle เข้าไปใน "vboxsf" group เพื่อให้มัน access เข้า shared drives ได้
# usermod -G vboxsf,dba oracle
# id oracle
uid=54321(oracle) gid=54321(oinstall) groups=54321(oinstall),54322(dba),54323(vboxsf)
9.สร้าง Shared Folder เพื่อสามารถเก็บไฟล์ต่างๆให้แชร์กันระหว่าง Host กับ Guest ได้โดยคลิกไปที่ Devices > Shared Folders Settings... คลิกสร้างทางด้านขวาแล้วเลือกให้เป็น Auto-mount กับ Make Permanent
Prepare Storage
1.สร้าง Shared Disks
ปิดเครื่องก่อน init 0
แล้วแอด harddisk เพิ่มเข้าไปตามต้องการโดยปรับให้เป็นแบบ Fixed Size
5.1 แก้ไฟล์ถ้าไม่มีก็สร้าง /etc/scsi_id.config เพื่อ configure SCSI devices as trusted
ใส่ไปตามนี้
options=-g
5.2 ดู SCSI_ID ของ shared disks ที่เราสร้างไว้
# /sbin/scsi_id -g -u -d /dev/sdb
1ATA_VBOX_HARDDISK_VBbd305c02-710a78b1
# /sbin/scsi_id -g -u -d /dev/sdc
1ATA_VBOX_HARDDISK_VB8db6505e-93acf98c
# /sbin/scsi_id -g -u -d /dev/sdd
1ATA_VBOX_HARDDISK_VBe47fab34-ff1b89f2
5.3 เอาค่าที่ได้ไปใส่ในไฟล์ /etc/udev/rules.d/99-oracle-asmdevices.rules แล้วกำหนด owner กับ permissions
KERNEL=="sdb1", BUS=="scsi", PROGRAM=="/sbin/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VBbd305c02-710a78b1",
NAME="asm1", OWNER="oracle", GROUP="oinstall", MODE="0660"
KERNEL=="sdc1", BUS=="scsi", PROGRAM=="/sbin/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VB8db6505e-93acf98c",
NAME="asm2", OWNER="oracle", GROUP="oinstall", MODE="0660"
KERNEL=="sdd1", BUS=="scsi", PROGRAM=="/sbin/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VBe47fab34-ff1b89f2",
NAME="asm3", OWNER="oracle", GROUP="oinstall", MODE="0660"
5.4 โหลด updated block device partition tables.
# /sbin/partprobe /dev/sdb1
# /sbin/partprobe /dev/sdc1
# /sbin/partprobe /dev/sdd1
5.5 เทส rules ว่าทำงานตามที่ต้องการไหม
/sbin/udevadm test /block/sdb/sdb1
/sbin/udevadm test /block/sdc/sdc1
/sbin/udevadm test /block/sdd/sdd1
5.6 Reload UDEV rules และ start UDEV
# /sbin/udevadm control --reload-rules
# /sbin/start_udev
5.7 Disks ควรเห็นได้จากคำสั่งตามด้านล่างนี้ ถ้าเกิดไม่เห็นแสดงว่าเราปรับ UDEV ผิดต้องแก้ไขก่อน
Clone Server
1.ปิดเครื่อง kitti-rac1
เมื่ออยู่หน้า VirtualBox Manager ให้คลิกขวาที่เครื่องของเราแล้วเลือก Clone...
2.ตั้งชื่อใหม่จาก oel-rac1 เป็น oel-rac2 และติ๊กถูกที่ Reinitialize the MAC address of all network cards
3.เลือก Full Clone
4.เมื่อ Clone เสร็จก็เปิดเครื่อง oel-rac2 แล้วแก้ config ต่างๆโดยเซต Network ตามด้านล่าง
3.เลือก "Install and Configure Oracle Grid Infrastructure for a Cluster" แล้วคลิก Next
$ srvctl status database -d KITTIRAC
Instance KITTIRAC1 is running on node kitti-rac1
Instance KITTIRAC2 is running on node kitti-rac2
เช็ค v$active_instances เพื่อดูว่า instance ไหนรันอยู่
เตรียมความพร้อมก่อนการติดตั้ง
RAM ทั้ง 2 เครื่องรวมกันควรเท่ากับหรือมากกว่า 9 GB
Disk ทั้ง 2 ควรแบ่งให้ local เครื่องละ 30GB ขึ้นไป
Prepare Network
1.เซต Network 3 ตัว
ตัวแรกเซตเป็น NAT
ตัวที่สองเซตเป็น Internal Network
ตัวที่สามเซตเป็น Host-only Adapter
2. เซต Host-only Network เพื่อใช้เป็น Public Network ของ RAC
- Start VirtualBox จากเมนู.
- เลือก "File > Preferences"
- คลิก "Network" ตรงแถบด้านซ้ายแล้วเลือกแท็บ "Host-only Networks"
- คลิก "Add host-only network (Ins)" ที่ปุ่ม + สีเขียวด้านขวา Network ชื่อ "VirtualBox Host-Only Ethernet Adapter" จะถูกสร้างขึ้นมา
คลิกขวาแล้วแก้ไขเราสามารถดูได้ว่า IP , Subnet ของ VirtualBox Host-only Network ถูกตั้งเป็นอะไรเราสามารถแก้ไขได้แต่ไม่ควรแก้ Subnet ให้ตรงกับ Subnet ที่เครื่องเราใช้จริง จากในตัวอย่างใช้ IP 192.168.172.1
3.เซต Network adapter ใน Linux
จากตัวอย่างเซตแบบนี้
- hostname: kitti-rac1.localdomain
- eth0: DHCP (Connect Automatically)
- eth1: IP=172.16.172.101, Subnet=255.255.0.0, Gateway=0.0.0.0, DNS=<blank> Search=<blank> (Connect Automatically)
- eth2: IP=192.168.172.101, Subnet=255.255.255.0, Gateway=<blank>, DNS=192.168.172.101,192.168.172.102 Search=localdomain (Connect Automatically)
4.แก้ไฟล์ /etc/hosts
127.0.0.1 localhost.localdomain localhost
# Public
192.168.172.101 kitti-rac1.localdomain kitti-rac1
192.168.172.102 kitti-rac2.localdomain kitti-rac2
# Private
172.16.172.101 kitti-rac1-priv.localdomain kitti-rac1-priv
172.16.172.102 kitti-rac2-priv.localdomain kitti-rac2-priv
# Virtual
192.168.172.103 kitti-rac1-vip.localdomain kitti-rac1-vip
192.168.172.104 kitti-rac2-vip.localdomain kitti-rac2-vip
# SCAN
192.168.172.105 kitti-scan.localdomain kitti-scan
192.168.172.106 kitti-scan.localdomain kitti-scan
192.168.172.107 kitti-scan.localdomain kitti-scan
5.ติดตั้ง dnsmasq เพื่อใช้ dns
# yum install dnsmasq
แก้ไฟล์ /etc/resolv.conf
search localdomain
nameserver 192.168.172.101
nameserver 192.168.172.102
*เพื่อป้องกัน /etc/resolv.conf ถูกเขียนทับโดย Network Manager เพราะเราเซต eth0 เป็น NAT เราจึงต้องทำการแก้ไฟล์ "/etc/sysconfig/network-scripts/ifcfg-eth0" โดยปรับ ONBOOT=no หลังจากนั้นลอง reboot เครื่อง
ลองสั่ง start service
# service dnsmasq stop
# service dnsmasq start
ลองสั่ง nslookup
# nslookup kitti-scan
Server: 192.168.172.1
Address: 192.168.172.1#53
Name: kitti-scan.localdomain
Address: 192.168.56.105
Name: kitti-scan.localdomain
Address: 192.168.56.106
Name: kitti-scan.localdomain
Address: 192.168.56.107
แก้ไฟล์ /etc/dnsmasq.conf โดยปรับ
local=/localdomain/
Prepare OS
1.แก้ไขไฟล์ "/etc/security/limits.d/90-nproc.conf" เพื่อแก้ปัญหา MOS Note [ID 1487773.1]
# แก้จาก
* soft nproc 1024
# เป็น
* - nproc 16384
2. Disable SElinux "/etc/selinux/config"
SELINUX=disabled
3.ปิดไฟวอ
service iptables stop
chkconfig iptables off
4.Disable Network Time Protocal (NTP) เพื่อเราจะได้ใช้ Oracle Cluster Time Synchronization Service (ctssd) เพื่อให้มันซิงค์วันที่และเวลาระหว่างทุกเครื่องใน RAC
service ntpd stop
chkconfig ntpd off
5.สร้าง Directories เพื่อเก็บ Software
mkdir -p /u01/app/12.1.0.2/grid
mkdir -p /u01/app/oracle/product/12.1.0.2
chown -R oracle:oinstall /u01
chmod -R 775 /u01/
6.Login user เป็น oracle แล้วใส่ใน .bash_profile
# Oracle Settings
export TMP=/tmp
export TMPDIR=$TMP
export ORACLE_HOSTNAME=kitti-rac1.localdomain
export ORACLE_UNQNAME=KITTIRAC
export ORACLE_BASE=/u01/app/oracle
export GRID_HOME=/u01/app/12.1.0.2/grid
export ORACLE_HOME=$ORACLE_BASE/product/12.1.0.2
export ORACLE_SID=KITTIRAC1
export ORACLE_TERM=xterm
export BASE_PATH=/usr/sbin:$PATH
export PATH=$ORACLE_HOME/bin:$BASE_PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
7. Reboot เครื่อง 1 ทีพอเสร็จแล้วให้กด Devices > Install Guest Additions CD image...
8.เพิ่ม user oracle เข้าไปใน "vboxsf" group เพื่อให้มัน access เข้า shared drives ได้
# usermod -G vboxsf,dba oracle
# id oracle
uid=54321(oracle) gid=54321(oinstall) groups=54321(oinstall),54322(dba),54323(vboxsf)
9.สร้าง Shared Folder เพื่อสามารถเก็บไฟล์ต่างๆให้แชร์กันระหว่าง Host กับ Guest ได้โดยคลิกไปที่ Devices > Shared Folders Settings... คลิกสร้างทางด้านขวาแล้วเลือกให้เป็น Auto-mount กับ Make Permanent
1.สร้าง Shared Disks
ปิดเครื่องก่อน init 0
แล้วแอด harddisk เพิ่มเข้าไปตามต้องการโดยปรับให้เป็นแบบ Fixed Size
2.เข้าไปที่ File > Virtual Media Manager... แล้วปรับให้ disk ที่เพิ่มเข้ามาใหม่เป็นประเภท Shareable
3.เปิดเครื่อง kitti-rac1 ขึ้นมาแล้วเข้าไปที่ user root เพื่อ config disks
disks ปัจจุบันเราสามารถเห็นได้จาก
ls /dev/sd*
/dev/sda /dev/sda1 /dev/sda2 /dev/sdb /dev/sdc /dev/sdd
4.ใช้คำสั่ง fdisk เพื่อแบ่ง partition โดยในตัวอย่างจะแบ่งของ sdb จนถึง sdd
# fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x54f59eed.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c') and change display units to
sectors (command 'u').
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-652, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-652, default 652):
Using default value 652
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
5.ตั้งค่า UDEV rules
สำหรับการใช้ Oracle ASM เพื่อใช้ Disks มันต้องสามารถระบุ devices และพวกมันต้องมี ownership และ permissions ที่ถูกต้องในที่นี้เราจะใช้ UDEV rules
5.1 แก้ไฟล์ถ้าไม่มีก็สร้าง /etc/scsi_id.config เพื่อ configure SCSI devices as trusted
ใส่ไปตามนี้
options=-g
5.2 ดู SCSI_ID ของ shared disks ที่เราสร้างไว้
# /sbin/scsi_id -g -u -d /dev/sdb
1ATA_VBOX_HARDDISK_VBbd305c02-710a78b1
# /sbin/scsi_id -g -u -d /dev/sdc
1ATA_VBOX_HARDDISK_VB8db6505e-93acf98c
# /sbin/scsi_id -g -u -d /dev/sdd
1ATA_VBOX_HARDDISK_VBe47fab34-ff1b89f2
5.3 เอาค่าที่ได้ไปใส่ในไฟล์ /etc/udev/rules.d/99-oracle-asmdevices.rules แล้วกำหนด owner กับ permissions
KERNEL=="sdb1", BUS=="scsi", PROGRAM=="/sbin/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VBbd305c02-710a78b1",
NAME="asm1", OWNER="oracle", GROUP="oinstall", MODE="0660"
KERNEL=="sdc1", BUS=="scsi", PROGRAM=="/sbin/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VB8db6505e-93acf98c",
NAME="asm2", OWNER="oracle", GROUP="oinstall", MODE="0660"
KERNEL=="sdd1", BUS=="scsi", PROGRAM=="/sbin/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VBe47fab34-ff1b89f2",
NAME="asm3", OWNER="oracle", GROUP="oinstall", MODE="0660"
5.4 โหลด updated block device partition tables.
# /sbin/partprobe /dev/sdb1
# /sbin/partprobe /dev/sdc1
# /sbin/partprobe /dev/sdd1
5.5 เทส rules ว่าทำงานตามที่ต้องการไหม
/sbin/udevadm test /block/sdb/sdb1
/sbin/udevadm test /block/sdc/sdc1
/sbin/udevadm test /block/sdd/sdd1
5.6 Reload UDEV rules และ start UDEV
# /sbin/udevadm control --reload-rules
# /sbin/start_udev
5.7 Disks ควรเห็นได้จากคำสั่งตามด้านล่างนี้ ถ้าเกิดไม่เห็นแสดงว่าเราปรับ UDEV ผิดต้องแก้ไขก่อน
Clone Server
1.ปิดเครื่อง kitti-rac1
เมื่ออยู่หน้า VirtualBox Manager ให้คลิกขวาที่เครื่องของเราแล้วเลือก Clone...
2.ตั้งชื่อใหม่จาก oel-rac1 เป็น oel-rac2 และติ๊กถูกที่ Reinitialize the MAC address of all network cards
3.เลือก Full Clone
4.เมื่อ Clone เสร็จก็เปิดเครื่อง oel-rac2 แล้วแก้ config ต่างๆโดยเซต Network ตามด้านล่าง
- hostname: kitti-rac2.localdomain
- eth0: DHCP (Connect Automatically)
- eth1: IP=172.16.172.102, Subnet=255.255.0.0, Gateway=0.0.0.0, DNS=<blank> Search=<blank> (Connect Automatically)
- eth2: IP=192.168.172.102, Subnet=255.255.255.0, Gateway=<blank>, DNS=192.168.172.101,192.168.172.102 Search=localdomain (Connect Automatically)
5.แก้ชื่อ Hostname ที่ไฟล์ /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=ol6-121-rac2.localdomain
6.แก้ MAC Address ของ eth0 , eth1 , eth2 ให้ตรงกับ Network Adapter ของมัน
แก้ที่ไฟล์ /etc/sysconfig/network-scripts/ifcfg-eth0 , /etc/sysconfig/network-scripts/ifcfg-eth1 , /etc/sysconfig/network-scripts/ifcfg-eth2
ที่ "HWADDR=..."
โดยดูจาก
เช่น
HWADDR=08:00:27:F1:66:6A
ทำให้ครบทั้ง 3 Adapter
*ตรวจสอบที่ /etc/sysconfig/network-scripts/ifcfg-eth0 ด้วยว่า ONBOOT=no หรือไม่ถ้าเป็น yes ให้ปรับเป็น no
7.แก้ /home/oracle/.bash_profile
export ORACLE_SID=KITTIRAC2
export ORACLE_HOSTNAME=kitti-rac2.localdomain
8.Restart kitti-rac2 server และ start kitti-rac1 ด้วย
9.ลอง ping ทดสอบดูว่าทั้ง public และ private ip สามารถใช้ได้หรือไม่
ping kitti-rac1
ping kitti-rac1-priv
ping kitti-rac2
ping kitti-rac2-priv
10.เช็ค SCAN ว่ายังสามารถ resolved ทั้งสอง node หรือไม่
# nslookup kitti-scan
Server: 192.168.172.101
Address: 192.168.172.101#53
Name: kitti-scan.localdomain
Address: 192.168.172.107
Name: kitti-scan.localdomain
Address: 192.168.172.105
Name: kitti-scan.localdomain
Address: 192.168.172.106
*ตอนนี้อย่าพึ่ง ping virtual ip เพราะตอนนี้มันยังใช้ไม่ได้
11.ปิดเครื่อง kitti-rac2 แล้วทำการแอด shared disk เข้าไปโดยเลือก Add Harddisk แล้วเลือก Choose existing disk
12.เช็คที่เครื่อง kitti-rac2 โดยสั่ง ls -l /dev/asm* ถ้าไม่ขึ้นตามนี้ให้ลอง config udev rules ใหม่ตามวิธีก่อนหน้า (ตั้งแต่ OEL 6.3 ขึ้นไปน่าจะขึ้นหมดไม่มีปัญหา)
# ls -l /dev/asm*
brw-rw---- 1 oracle oinstall 8, 17 Apr 8 10:24 /dev/asm1
brw-rw---- 1 oracle oinstall 8, 33 Apr 8 10:24 /dev/asm2
brw-rw---- 1 oracle oinstall 8, 49 Apr 8 10:24 /dev/asm3
Install the Grid Infrastructure
1.เปิดเครื่องขึ้นมาทั้ง 2 เครื่องแล้วติดตั้ง rpm นี้ไว้ทั้ง 2 เครื่อง
# cd /media/sf_Oracle12c/grid/rpm
# rpm -Uvh cvuqdisk*
2.Login ไปที่ user oracle ของเครื่อง kitti-rac1 แล้วสั่ง
$ cd /media/sf_Oracle12c/grid
$ ./runInstaller
3.เลือก "Install and Configure Oracle Grid Infrastructure for a Cluster" แล้วคลิก Next
4.เลือก "Configure a Standard Cluster" แล้วคลิก Next
5.เลือก "Typical Installation" แล้วคลิก Next
6.ตั้งชื่อ SCAN ให้ตรงหลังจากนั้นคลิก Add...
7.ใส่ค่าลอง node kitti-rac2 ลงไป
8.คลิก "SSH Connectivity..." ใส่ password ของ oracle user อีกเครื่องนึงให้ถูกต้องจากนั้นกด Setup แล้วคลิก Next
9.เช็ค public และ private network ว่าถูกต้อง ถ้าหากมี interface ที่เป็น NAT อยู่ด้วยให้เลือกเป็น Do Not Use
10.ใส่ "/u01/app/12.1.0.2/grid" ลงไปใน Software Location แล้วเลือก Cluster Registry Storage Type เป็น Oracle Automatic Storage Management
11.ปรับ Redundancy เป็น "External" แล้วคลิก Change Discovery Path... ใส่ค่าเป็น "/dev/asm*" จะขึ้น disks available มาแสดง
12.เลือก default inventory directory แล้วคลิก Next
13.ถ้าเรามี root scripts ให้รันอัตโนมัติ แต่แนะนำให้ทำ Manual ดีกว่า คลิก Next
14.รอซักพักจน Prerequisite checks เสร็จถ้ามีปัญหาใดๆให้ลองกด "Fix & Check Again" ถ้าสามารถแก้ไขได้แล้วยังมีปัญหาอีกหากไม่มีผลกระทบอะไรสามารถกด Ignore All แล้วคลิก Next
15.ตรวจสอบ summary ให้เรียบร้อยหากไม่มีอะไรผิดพลาดสามารถคลิก Install เพื่อเริ่มการติดตั้งได้เลย
16.รอ...
17.รันสคริปต์ด้วย root ทั้ง 2 node
18.หลังจากรันสคริปต์หมดก็รออีกซักพักก็จะเสร็จสมบูรณ์
Check status of the installation
# crsctl status res -t
--------------------------------------------------------------------------------
Name Target State Server State details
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
ora.DATA.dg
ONLINE ONLINE kitti-rac1 STABLE
ONLINE ONLINE kitti-rac2 STABLE
ora.LISTENER.lsnr
ONLINE ONLINE kitti-rac1 STABLE
ONLINE ONLINE kitti-rac2 STABLE
ora.asm
ONLINE ONLINE kitti-rac1 Started,STABLE
ONLINE ONLINE kitti-rac2 Started,STABLE
ora.net1.network
ONLINE ONLINE kitti-rac1 STABLE
ONLINE ONLINE kitti-rac2 STABLE
ora.ons
ONLINE ONLINE kitti-rac1 STABLE
ONLINE ONLINE kitti-rac2 STABLE
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.LISTENER_SCAN1.lsnr
1 ONLINE ONLINE kitti-rac2 STABLE
ora.LISTENER_SCAN2.lsnr
1 ONLINE ONLINE kitti-rac1 STABLE
ora.LISTENER_SCAN3.lsnr
1 ONLINE ONLINE kitti-rac1 STABLE
ora.MGMTLSNR
1 ONLINE ONLINE kitti-rac1 169.254.199.72 172.1
6.172.101,STABLE
ora.cvu
1 ONLINE ONLINE kitti-rac1 STABLE
ora.kitti-rac1.vip
1 ONLINE ONLINE kitti-rac1 STABLE
ora.kitti-rac2.vip
1 ONLINE ONLINE kitti-rac2 STABLE
ora.mgmtdb
1 ONLINE ONLINE kitti-rac1 Open,STABLE
ora.oc4j
1 ONLINE ONLINE kitti-rac1 STABLE
ora.scan1.vip
1 ONLINE ONLINE kitti-rac2 STABLE
ora.scan2.vip
1 ONLINE ONLINE kitti-rac1 STABLE
ora.scan3.vip
1 ONLINE ONLINE kitti-rac1 STABLE
--------------------------------------------------------------------------------
Install the Database Software
1.เช็คให้แน่ใจว่าทั้ง 2 เครื่องเปิดอยู่
2.Login ไปที่ user oracle ของเครื่อง kitti-rac1 แล้วสั่ง
$ cd /media/sf_Oracle12c/database
$ ./runInstaller
3.เอาติ๊กถูกที่ Security Update ออกแล้วคลิก Next (จะมีข้อความเตือนให้คลิก OK)
4.ติ๊กเลือก Install database software only แล้วคลิก Next
5.ติ๊กเลือก Oracle Real Application Clusters database installation แล้วคลิก Next
6.ติ๊กเลือก nodes ที่เราต้องการทำเป็น RAC แล้วคลิก Next
7.เลือกภาษาที่ต้องการแล้วคลิก Next
8.ติ๊ก Enterprise Edition แล้วคลิก Next
9.ใส่ /u01/app/oracle เป็น Oracle Base และ /u01/app/oracle/product/12.1.0.2 เป็น Software Location
หลังจากนั้นคลิก Next
10.เลือก OS Group ที่ต้องการหลังจากนั้นคลิก Next
11.รอ prerequisite check จนเสร็จถ้าหากมีปัญหาใดๆให้ลองกด "Fix & Check Again" หรือติ๊ก "Ignore All" แล้วคลิก Next
12.ตรวจสอบ summary ให้เรียบร้อยหากไม่มีอะไรผิดพลาดสามารถคลิก Install เพื่อเริ่มการติดตั้งได้เลย
13.รอ...
14.รันสคริปต์ด้วย root ทั้ง 2 node
15.เสร็จสิ้น...
Create Database
1.เช็คให้แน่ใจว่าทั้ง 2 เครื่องเปิดอยู่
2.Login ไปที่ user oracle ของเครื่อง kitti-rac1 แล้วสั่ง
$ dbca
3.เลือก Create Database แล้วคลิก Next
4.เลือกโหมดการสร้างตามต้องการแล้วคลิก Next
5.รอ prerequisite check จนเสร็จถ้าหากมีปัญหาใดๆให้แก้ไขก่อนหรือจะ "Ignore All" แล้วคลิก Next
6.ตรวจสอบ summary ให้เรียบร้อยหากไม่มีอะไรผิดพลาดสามารถคลิก Install เพื่อเริ่มการติดตั้งได้เลย
7.รอ...
8.สร้างเสร็จแล้วถ้าอยากเปลี่ยนพาสเวิร์ดให้กด Password Management... หรือจะเปลี่ยนทีหลังก็ได้
Check the RAC status
$ srvctl config database -d KITTIRAC
Database unique name: KITTIRAC
Database name: KITTIRAC
Oracle home: /u01/app/oracle/product/12.1.0.2
Oracle user: oracle
Spfile: +DATA/KITTIRAC/PARAMETERFILE/spfile.288.876578023
Password file: +DATA/KITTIRAC/PASSWORD/pwdkittirac.276.876577021
Domain:
Start options: open$ sqlplus / as sysdba
SQL*Plus: Release 12.1.0.2.0 Production on Thu Apr 9 14:04:53 2015
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options
SQL> select inst_name from v$active_instances;
INST_NAME
--------------------------------------------------------------------------------
kitti-rac1.localdomain:KITTIRAC1
kitti-rac2.localdomain:KITTIRAC2
Stop options: immediate
Database role: PRIMARY
Management policy: AUTOMATIC
Server pools:
Disk Groups: DATA
Mount point paths:
Services:
Type: RAC
Start concurrency:
Stop concurrency:
OSDBA group: dba
OSOPER group:
Database instances: KITTIRAC1,KITTIRAC2
Configured nodes: kitti-rac1,kitti-rac2
Database is administrator managed
Instance KITTIRAC1 is running on node kitti-rac1
Instance KITTIRAC2 is running on node kitti-rac2
เช็ค v$active_instances เพื่อดูว่า instance ไหนรันอยู่
$ sqlplus / as sysdba
SQL*Plus: Release 12.1.0.2.0 Production on Thu Apr 9 14:04:53 2015
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options
SQL> select inst_name from v$active_instances;
INST_NAME
--------------------------------------------------------------------------------
kitti-rac1.localdomain:KITTIRAC1
kitti-rac2.localdomain:KITTIRAC2
ตัวอย่างบางส่วนศึกษามาจาก http://oracle-base.com/articles/12c/oracle-db-12cr1-rac-installation-on-oracle-linux-6-using-virtualbox.php
ตัวอย่างบางส่วนศึกษามาจาก http://oracle-base.com/articles/12c/oracle-db-12cr1-rac-installation-on-oracle-linux-6-using-virtualbox.php
วันเสาร์ที่ 28 มีนาคม พ.ศ. 2558
สร้าง Job Scheduler ง่ายๆด้วย Oracle Scheduler
Oracle Scheduler มีประโยชน์ในการกำหนดงานให้ทำแบบอัตโนมัติตามเวลาหรือเหตุการณ์ที่เราได้ตั้งไว้
และมันยังสามารถตั้งค่าให้งานนึงรันต่อจากอีกงานนึงก็ได้ (Job chain) อีกทั้งยังประยุกต์ใช้ร่วมกับ Resource Manager เพื่อกำหนด Priorities ต่างๆได้อีกด้วย
เราสามารถสร้าง Job ให้รันงานได้หลายประเภทเช่น PLSQL_BLOCK , STORED_PROCEDURE , หรือ EXECUTABLE
โดย PLSQL_BLOCK คือ SQL statement , PL/SQL anonymous block
STORED_PROCEDURE คือ stored procedure ซึ่งสามารถเป็น pl/sql , java หรือ external procedure ที่เขียนด้วย C
EXECUTABLE คือชุด OS command , executable binary file , หรือ shell script หรือ batch file
โดยเมื่อเรากำหนดประเภทของมันแล้วเราต้องกำหนด Action ให้ตรงกันด้วย
ตัวอย่างการสร้าง Job อย่างง่ายด้วย DBMS_SCHEDULER
1. สร้าง table ไว้เก็บวันที่และเวลา
create table num (c1 date);
2. ปรับรูปแบบวันที่ให้ดูนาทีได้
alter session set nls_date_format='dd-mm-yy hh24:mi:ss';
3. สร้าง job ขึ้นมาโดยสั่งให้ Insert วันที่กับเวลาลงใน TIMES table โดยให้ทำทุกๆ 1 นาที
begin
dbms_scheduler.create_job(
job_name=>'savedate',
job_type=>'plsql_block',
job_action=>'insert into times values(sysdate);',
start_date=>sysdate,
repeat_interval=>'freq=minutely;interval=1',
enabled=>true,
auto_drop=>false);
end;
/
4. ลอง query ดู
select * from times;
C1
-----------------
28-03-15 22:48:57
28-03-15 22:49:57
28-03-15 22:50:57
5. เราสามารถยกเลิกและลบ JOB ของเราทิ้งได้ด้วย
exec dbms_scheduler.disable('savedate');
exec dbms_scheduler.drop_job('savedate');
เราสามารถสร้าง Program และ Schedule ขึ้นมาแล้วให้ JOB อื่นมาเรียก Program และ Schedule ของเราได้อีกหลายๆครั้ง เป็นการ Reuse Operation ได้โดยเรากำหนด Action ไว้ที่ Program และเวลาที่รันไว้ที่ Schedule แทน
ตัวอย่าง
1. สร้าง Program ขึ้นมาก่อน
begin
dbms_scheduler.create_program(
program_name=>'savedate',
program_action=>'insert into times values(sysdate);',
program_type=>'plsql_block',
comments=>'Insert current date into the TIMES table',
enabled=>true);
end;
/
NOTE : JOB และ PROGRAM แชร์ Namespace กันเราไม่สามารถสร้าง JOB และ PROGRAM มีชื่อเหมือนกันได้
2. สร้าง Schedule ขึ้นมาและกำหนดว่ารันทุก 3 นาที
begin
dbms_scheduler.create_schedule(
schedule_name=>'every_three_minute',
start_date=>sysdate,
repeat_interval=>'freq=minutely;interval=3',
comments=>'Every 3 minutes');
end;
/
3. สร้าง JOB ขึ้นมาแล้วสั่งให้ใช้ Program กับ Schedule ที่มีอยู่
begin
dbms_scheduler.create_job(
job_name=>'increase_date',
program_name=>'savedate',
schedule_name=>'every_three_minute',
enabled=>true,
auto_drop=>false);
end;
/
4. ลอง query ดู
select * from times;
C1
-----------------
28-03-15 23:05:07
28-03-15 23:08:07
28-03-15 23:11:07
28-03-15 23:14:07
ตัวอย่างที่ 2 สร้าง job เพื่อทำ begin backup และ end backup (สร้างบน SYS หรือ SYSTEM) โดยให้รันวันละ 1 ครั้งตามเวลาที่กำหนด
begin
dbms_scheduler.create_job(
job_name=>'begin_backup',
job_type=>'plsql_block',
job_action=>'begin
execute immediate ''alter database begin backup''; end;',
start_date=>to_date('17-JUL-2017 17:28:00','DD-MON-YYYY HH24:MI:SS'),
repeat_interval=>'freq=daily;interval=1',
enabled=>true,
auto_drop=>false);
end;
/
begin
dbms_scheduler.create_job(
job_name=>'end_backup',
job_type=>'plsql_block',
job_action=>'begin
execute immediate ''alter database end backup''; end;',
start_date=>to_date('17-JUL-2017 17:33:00','DD-MON-YYYY HH24:MI:SS'),
repeat_interval=>'freq=daily;interval=1',
enabled=>true,
auto_drop=>false);
end;
/
ตัวอย่างบางส่วนใช้จากหนังสือ OCP Oracle 11g Administration II Exam Guide
และมันยังสามารถตั้งค่าให้งานนึงรันต่อจากอีกงานนึงก็ได้ (Job chain) อีกทั้งยังประยุกต์ใช้ร่วมกับ Resource Manager เพื่อกำหนด Priorities ต่างๆได้อีกด้วย
เราสามารถสร้าง Job ให้รันงานได้หลายประเภทเช่น PLSQL_BLOCK , STORED_PROCEDURE , หรือ EXECUTABLE
โดย PLSQL_BLOCK คือ SQL statement , PL/SQL anonymous block
STORED_PROCEDURE คือ stored procedure ซึ่งสามารถเป็น pl/sql , java หรือ external procedure ที่เขียนด้วย C
EXECUTABLE คือชุด OS command , executable binary file , หรือ shell script หรือ batch file
โดยเมื่อเรากำหนดประเภทของมันแล้วเราต้องกำหนด Action ให้ตรงกันด้วย
ตัวอย่างการสร้าง Job อย่างง่ายด้วย DBMS_SCHEDULER
1. สร้าง table ไว้เก็บวันที่และเวลา
create table num (c1 date);
2. ปรับรูปแบบวันที่ให้ดูนาทีได้
alter session set nls_date_format='dd-mm-yy hh24:mi:ss';
3. สร้าง job ขึ้นมาโดยสั่งให้ Insert วันที่กับเวลาลงใน TIMES table โดยให้ทำทุกๆ 1 นาที
begin
dbms_scheduler.create_job(
job_name=>'savedate',
job_type=>'plsql_block',
job_action=>'insert into times values(sysdate);',
start_date=>sysdate,
repeat_interval=>'freq=minutely;interval=1',
enabled=>true,
auto_drop=>false);
end;
/
4. ลอง query ดู
select * from times;
C1
-----------------
28-03-15 22:48:57
28-03-15 22:49:57
28-03-15 22:50:57
5. เราสามารถยกเลิกและลบ JOB ของเราทิ้งได้ด้วย
exec dbms_scheduler.disable('savedate');
exec dbms_scheduler.drop_job('savedate');
เราสามารถสร้าง Program และ Schedule ขึ้นมาแล้วให้ JOB อื่นมาเรียก Program และ Schedule ของเราได้อีกหลายๆครั้ง เป็นการ Reuse Operation ได้โดยเรากำหนด Action ไว้ที่ Program และเวลาที่รันไว้ที่ Schedule แทน
ตัวอย่าง
1. สร้าง Program ขึ้นมาก่อน
begin
dbms_scheduler.create_program(
program_name=>'savedate',
program_action=>'insert into times values(sysdate);',
program_type=>'plsql_block',
comments=>'Insert current date into the TIMES table',
enabled=>true);
end;
/
NOTE : JOB และ PROGRAM แชร์ Namespace กันเราไม่สามารถสร้าง JOB และ PROGRAM มีชื่อเหมือนกันได้
2. สร้าง Schedule ขึ้นมาและกำหนดว่ารันทุก 3 นาที
begin
dbms_scheduler.create_schedule(
schedule_name=>'every_three_minute',
start_date=>sysdate,
repeat_interval=>'freq=minutely;interval=3',
comments=>'Every 3 minutes');
end;
/
3. สร้าง JOB ขึ้นมาแล้วสั่งให้ใช้ Program กับ Schedule ที่มีอยู่
begin
dbms_scheduler.create_job(
job_name=>'increase_date',
program_name=>'savedate',
schedule_name=>'every_three_minute',
enabled=>true,
auto_drop=>false);
end;
/
4. ลอง query ดู
select * from times;
C1
-----------------
28-03-15 23:05:07
28-03-15 23:08:07
28-03-15 23:11:07
28-03-15 23:14:07
ตัวอย่างที่ 2 สร้าง job เพื่อทำ begin backup และ end backup (สร้างบน SYS หรือ SYSTEM) โดยให้รันวันละ 1 ครั้งตามเวลาที่กำหนด
begin
dbms_scheduler.create_job(
job_name=>'begin_backup',
job_type=>'plsql_block',
job_action=>'begin
execute immediate ''alter database begin backup''; end;',
start_date=>to_date('17-JUL-2017 17:28:00','DD-MON-YYYY HH24:MI:SS'),
repeat_interval=>'freq=daily;interval=1',
enabled=>true,
auto_drop=>false);
end;
/
begin
dbms_scheduler.create_job(
job_name=>'end_backup',
job_type=>'plsql_block',
job_action=>'begin
execute immediate ''alter database end backup''; end;',
start_date=>to_date('17-JUL-2017 17:33:00','DD-MON-YYYY HH24:MI:SS'),
repeat_interval=>'freq=daily;interval=1',
enabled=>true,
auto_drop=>false);
end;
/
ตัวอย่างบางส่วนใช้จากหนังสือ OCP Oracle 11g Administration II Exam Guide
วันจันทร์ที่ 24 พฤศจิกายน พ.ศ. 2557
ORA-14452: attempt to create, alter or drop an index on temporary table already in use
บางทีเราเห็นว่าไม่มีอะไรรันกับ object นั้นแล้วพอจะ drop มันก็ดันแจ้งว่ามีคนใช้อยู่
เราสามารถใช้ query ประมาณนี้เพื่อหา user ที่เป็นคน lock object นั้นอยู่แล้วค่อย kill ออกได้ครับ
select * from v$lock where id1 = (select object_id from dba_objects
where owner = 'KITTI' and object_name = 'DEPARTMENTS');
where owner = 'KITTI' and object_name = 'DEPARTMENTS');
วันอาทิตย์ที่ 23 พฤศจิกายน พ.ศ. 2557
ORA-06553: PLS-213: package STANDARD not accessible
Error นี้อาจเกิดขึ้นเพราะเรา Create Database ผ่าน command เองโดยไม่ได้ใช้ DBCA Tool
ซึ่งเราอาจ login ด้วย RMAN ไม่ได้และไม่สามารถ Query Data Dictionary Views ได้ด้วย
ซึ่งปัญหานี้ส่วนใหญ่มาจากที่เราไม่มี catalog database กับ procedures
ลองแก้ด้วยการรันสคริปต์ catalog.sql กับ catproc.sql ที่อยู่ใน $ORACLE_HOME/rdbms/admin/
SQL> @?/rdbms/admin/catalog.sql
...
...
...
...
SQL> @?/rdbms/admin/catproc.sql
...
...
...
...
เมื่อรันเสร็จลอง Query Data Dictionary Views และลอง Connect เข้า RMAN ดูครับ
ซึ่งเราอาจ login ด้วย RMAN ไม่ได้และไม่สามารถ Query Data Dictionary Views ได้ด้วย
ซึ่งปัญหานี้ส่วนใหญ่มาจากที่เราไม่มี catalog database กับ procedures
ลองแก้ด้วยการรันสคริปต์ catalog.sql กับ catproc.sql ที่อยู่ใน $ORACLE_HOME/rdbms/admin/
SQL> @?/rdbms/admin/catalog.sql
...
...
...
...
SQL> @?/rdbms/admin/catproc.sql
...
...
...
...
เมื่อรันเสร็จลอง Query Data Dictionary Views และลอง Connect เข้า RMAN ดูครับ
วันเสาร์ที่ 22 พฤศจิกายน พ.ศ. 2557
Resumable Space Allocation
Resumable space allocation จะช่วยให้ลดปัญหางานที่ต้องทำแล้วเกิดพื้นที่เก็บข้อมูลเต็ม แล้วลดเวลาที่ต้องรันใหม่ด้วยการระงับ (suspending) งานนั้นไว้ก่อนแทนที่จะยกเลิก (Terminate) งานนั้นเลย
ในขณะที่ Operation ถูก suspend DBA สามารถเพิ่ม disk space ไปที่ tablespace นั้นหรือเพิ่ม quota ให้กับ user นั้นๆได้ เมื่อเราเพิ่มเสร็จแล้ว Operation ที่ถูกระงับจะเริ่่มทำงานต่อไปโดยอัตโนมัติ
ทำความเข้าใจกับ Resumable Space Allocation
ถ้า statement ถูกระงับ transaction ที่เป็นเจ้าของ statement นั้นจะถูกระงับไปด้วย
เงื่อนไขตามนี้สามารถทำให้เกิดการ suspend แล้วใช้ resumable space allocation ได้
- Operation รันจน Permanent หรือ Temporary tablespace เต็ม
- Extents ถึงค่า Maximum ของ Tablespace นั้น
- User ใช้งานจนเกิน quota
เราสามารถควบคุมระยะเวลาที่ statement จะถูก suspend ค่า default คือ 2 ชั่วโมง หากไม่มีการเพิ่ม disk space หรือ quota เข้าไปมันจะเด้ง error message ขึ้นมาที่ user หรือ application นั้น
Command 4 ประเภทที่สามารถ resumable :
- SELECT : SELECT statements จะเข้าสู่การ resumable ได้ในกรณีเดียวคือรันจน temporary tablespace เต็มเมื่อเรามีการทำ sort operation เช่น ORDER BY , DISTINCT , หรือ UNION
- DML Commands : การ INSERT , UPDATE , DELETE สามารถทำให้ tablespace เต็มได้ ในกรณีของ DELETE อาจทำให้ undo tablespace เต็ม
- SQL*Loader : จาก command sqlldr เราสามารถเซต RESUMABLE parameter เป็น TRUE เราสามารถกำหนดชื่อของ resumable operation ด้วย RESUMABLE_NAME parameter ได้ด้วยตลอดจน resumable timeout ด้วย RESUMABLE_TIMEOUT parameter
- DDL Commands : ทุก DDL commands ที่ต้องใช้ disk space สำหรับ segments ใหม่หรือที่มีอยู่แล้วอาจ resumable ได้เช่น
-- CREATE TABLE . . . AS SELECT (CTAS)
-- CREATE INDEX
-- ALTER TABLE . . . [MOVE | SPLIT] PARTITION
-- ALTER INDEX . . . REBUILD
-- ALTER INDEX . . . [REBUILD | SPLIT] PARTITION
-- CREATE MATERIALIZED VIEW
การตั้งค่า Resumable Space Allocation
เราสามารถเปิดใช้งาน Resumable Space Allocation ได้ง่ายๆโดยเซตระดับ Instance ด้วย RESUMABLE_TIMEOUT initialization parameter หรือระดับ session ด้วย ALTER SESSION command
ถ้าเราเซต RESUMABLE_TIMEOUT ให้มีค่ามากกว่า 0 จะเป็นการเปิดใช้งาน Resumable Space Allocation โดยค่าที่เราเซตเข้าไปจะเป็นระยะเวลาที่ Operation จะถูก suspend ไว้และมันเป็ฯ dynamic parameter เราจึงสามารถเซตได้โดยไม่ต้องรีสตาร์ท
มีหน่วยเป็นวินาทีเ่ช่น
SQL> ALTER SYSTEM SET RESUMABLE_TIMEOUT = 7200; --เซตไว้ 2 ชั่วโมง
ถ้าเราเปิดใช้ระดับ system ทุก sessions จะสามารถใช้ Resumable Space Allocation ได้ ถ้าเราต้องการให้ users ไหนสามารถควบคุมการใช้งานได้มากขึ้นเราสามารถให้สิทธิ์ในการควบคุมเวลา suspend ของ user นั้นเองได้ด้วยการ
SQL> GRANT RESUMABLE TO users;
เมื่อ user ได้ RESUMABLE privilege แล้วจะสามารถเปิดใช้งาน resumable และตั้งเวลาเองได้ผ่าน ALTER SESSION command เช่น
SQL> ALTER SESSION ENABLE RESUMABLE;
SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 10000;
เราสามารถดูข้อมูล resumable ได้ผ่าน data dictionary DBA_RESUMABLE , USER_RESUMABLE เราสามารถเปิดใช้ได้ด้วยการเซต NAME มันลงไป
SQL> ALTER SESSION ENABLE RESUMABLE NAME 'Create Big Table';
SQL> select user_id,session_id,status,name,sql_text from dba_resumable;
USER_ID SESSION_ID STATUS NAME SQL_TEXT
------------ ----------------- ------------ ------------------------- --------------------------------------------------
85 124 NORMAL Create Big Table create table sale_history as select
* from sale_orders;
Session สามารถปิดการใช้งาน resumable ได้โดย
SQL> ALTER SESSION DISABLE RESUMABLE;
ประยุกต์ใช้กับ Trigger
เราสามารถสร้าง Trigger AFTER SUSPEND system event เพื่อแจ้งเตือนทาง email ให้กับ User ที่เรา focus และ DBA รับทราบเช่น
CREATE OR REPLACE TRIGGER resumable_notify
AFTER SUSPEND ON DATABASE
DECLARE
-- ประกาศตัวแปรถ้าต้องการ
BEGIN
DBMS_RESUMABLE.SPACE_ERROR_INFO( . . . ); --เช็คข้อมูล user id , ใน DBA_RESUMABLEจะ return ค่าเป็น boolean ถ้าไม่สามารถหาข้อมูล space error ได้จะ return FALSE
IF object_type = 'TABLE' and object_owner = 'HR' THEN
DBMS_RESUMABLE.SET_TIMEOUT(7200);
UTL_MAIL.SEND('orakitti@example.com', . . .);
ELSE -- ยกเลิก statement อื่นที่ถูก suspend ไว้
DBMS_RESUMABLE.ABORT( . . . );
END IF;
END;
ตัวอย่างการใช้งาน
1. Grant resumable ให้ HR ก่อน
2. สร้าง Tablespace มี 1 datafile ขนาด 10M ขึ้นมาเพื่อทดสอบ
3. Connect เข้า HR แล้วลองวนลูปสร้าง table เพื่อให้ tablespace เต็ม
4. Enable RESUMABLE และตั้งเวลาไว้ 3600 วินาที (1 ชั่ืวโมง)

5. ลองสร้างเพิ่มอีก Table นึงจะดูเหมือนว่ามันแฮ้งค์และมีข้อมูลขึ้นมาใน Alert Log ด้วย
Sat Nov 22 23:35:02 2014
statement in resumable session 'User HR(85), Session 520, Instance 1' was suspended due to
ORA-01658: unable to create INITIAL extent for segment in tablespace KITTI_TBS
มันจะขึ้นใน EM ตรง Alert section ด้วย
6. จาก Admin user เราจะ Query DBA_RESUMABLE เพื่อดูข้อมูลเกี่ยวกับ session ที่ถูก suspend
7. DBA ได้เพิ่ม datafile เข้าไปที่ tablespace KITTI_TBS อีก 1 ไฟล์
เมื่อเพิ่มเข้าไปเสร็จแล้ว user HR สามารถทำ Operation ต่อได้โดยอัตโนมัติ ในที่นี้คือ Create Table
และ Alert Log ก็แจ้งข้อความว่า Statement ได้ถูก resume แล้ว
Sat Nov 22 23:49:49 2014
statement in resumable session 'User HR(85), Session 520, Instance 1' was resumed
8. Query DBA_RESUMABLE อีกครั้งเพื่อยืนยันว่า Operation resumable แล้ว
** ถ้ามี session ถูก suspend จะมีข้อมูลขึ้นมาใน V$SESSION_WAIT ที่คอลัมน์ EVENT ว่า "statement suspended, wait error to be cleared"
เราควรแจ้งเตือน User ด้วยวิธีการใดๆก็ได้ (เช่น Trigger ส่งอีเมล) เพื่อให้ User เข้าใจว่าเกิดเหตุการ Suspend ขึ้น
Ref : OCP Oracle 11g Administration II Exam Guide
ในขณะที่ Operation ถูก suspend DBA สามารถเพิ่ม disk space ไปที่ tablespace นั้นหรือเพิ่ม quota ให้กับ user นั้นๆได้ เมื่อเราเพิ่มเสร็จแล้ว Operation ที่ถูกระงับจะเริ่่มทำงานต่อไปโดยอัตโนมัติ
ทำความเข้าใจกับ Resumable Space Allocation
ถ้า statement ถูกระงับ transaction ที่เป็นเจ้าของ statement นั้นจะถูกระงับไปด้วย
เงื่อนไขตามนี้สามารถทำให้เกิดการ suspend แล้วใช้ resumable space allocation ได้
- Operation รันจน Permanent หรือ Temporary tablespace เต็ม
- Extents ถึงค่า Maximum ของ Tablespace นั้น
- User ใช้งานจนเกิน quota
เราสามารถควบคุมระยะเวลาที่ statement จะถูก suspend ค่า default คือ 2 ชั่วโมง หากไม่มีการเพิ่ม disk space หรือ quota เข้าไปมันจะเด้ง error message ขึ้นมาที่ user หรือ application นั้น
Command 4 ประเภทที่สามารถ resumable :
- SELECT : SELECT statements จะเข้าสู่การ resumable ได้ในกรณีเดียวคือรันจน temporary tablespace เต็มเมื่อเรามีการทำ sort operation เช่น ORDER BY , DISTINCT , หรือ UNION
- DML Commands : การ INSERT , UPDATE , DELETE สามารถทำให้ tablespace เต็มได้ ในกรณีของ DELETE อาจทำให้ undo tablespace เต็ม
- SQL*Loader : จาก command sqlldr เราสามารถเซต RESUMABLE parameter เป็น TRUE เราสามารถกำหนดชื่อของ resumable operation ด้วย RESUMABLE_NAME parameter ได้ด้วยตลอดจน resumable timeout ด้วย RESUMABLE_TIMEOUT parameter
- DDL Commands : ทุก DDL commands ที่ต้องใช้ disk space สำหรับ segments ใหม่หรือที่มีอยู่แล้วอาจ resumable ได้เช่น
-- CREATE TABLE . . . AS SELECT (CTAS)
-- CREATE INDEX
-- ALTER TABLE . . . [MOVE | SPLIT] PARTITION
-- ALTER INDEX . . . REBUILD
-- ALTER INDEX . . . [REBUILD | SPLIT] PARTITION
-- CREATE MATERIALIZED VIEW
การตั้งค่า Resumable Space Allocation
เราสามารถเปิดใช้งาน Resumable Space Allocation ได้ง่ายๆโดยเซตระดับ Instance ด้วย RESUMABLE_TIMEOUT initialization parameter หรือระดับ session ด้วย ALTER SESSION command
ถ้าเราเซต RESUMABLE_TIMEOUT ให้มีค่ามากกว่า 0 จะเป็นการเปิดใช้งาน Resumable Space Allocation โดยค่าที่เราเซตเข้าไปจะเป็นระยะเวลาที่ Operation จะถูก suspend ไว้และมันเป็ฯ dynamic parameter เราจึงสามารถเซตได้โดยไม่ต้องรีสตาร์ท
มีหน่วยเป็นวินาทีเ่ช่น
SQL> ALTER SYSTEM SET RESUMABLE_TIMEOUT = 7200; --เซตไว้ 2 ชั่วโมง
ถ้าเราเปิดใช้ระดับ system ทุก sessions จะสามารถใช้ Resumable Space Allocation ได้ ถ้าเราต้องการให้ users ไหนสามารถควบคุมการใช้งานได้มากขึ้นเราสามารถให้สิทธิ์ในการควบคุมเวลา suspend ของ user นั้นเองได้ด้วยการ
SQL> GRANT RESUMABLE TO users;
เมื่อ user ได้ RESUMABLE privilege แล้วจะสามารถเปิดใช้งาน resumable และตั้งเวลาเองได้ผ่าน ALTER SESSION command เช่น
SQL> ALTER SESSION ENABLE RESUMABLE;
SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 10000;
เราสามารถดูข้อมูล resumable ได้ผ่าน data dictionary DBA_RESUMABLE , USER_RESUMABLE เราสามารถเปิดใช้ได้ด้วยการเซต NAME มันลงไป
SQL> ALTER SESSION ENABLE RESUMABLE NAME 'Create Big Table';
SQL> select user_id,session_id,status,name,sql_text from dba_resumable;
USER_ID SESSION_ID STATUS NAME SQL_TEXT
------------ ----------------- ------------ ------------------------- --------------------------------------------------
85 124 NORMAL Create Big Table create table sale_history as select
* from sale_orders;
Session สามารถปิดการใช้งาน resumable ได้โดย
SQL> ALTER SESSION DISABLE RESUMABLE;
ประยุกต์ใช้กับ Trigger
เราสามารถสร้าง Trigger AFTER SUSPEND system event เพื่อแจ้งเตือนทาง email ให้กับ User ที่เรา focus และ DBA รับทราบเช่น
CREATE OR REPLACE TRIGGER resumable_notify
AFTER SUSPEND ON DATABASE
DECLARE
-- ประกาศตัวแปรถ้าต้องการ
BEGIN
DBMS_RESUMABLE.SPACE_ERROR_INFO( . . . ); --เช็คข้อมูล user id , ใน DBA_RESUMABLEจะ return ค่าเป็น boolean ถ้าไม่สามารถหาข้อมูล space error ได้จะ return FALSE
IF object_type = 'TABLE' and object_owner = 'HR' THEN
DBMS_RESUMABLE.SET_TIMEOUT(7200);
UTL_MAIL.SEND('orakitti@example.com', . . .);
ELSE -- ยกเลิก statement อื่นที่ถูก suspend ไว้
DBMS_RESUMABLE.ABORT( . . . );
END IF;
END;
ตัวอย่างการใช้งาน
1. Grant resumable ให้ HR ก่อน
2. สร้าง Tablespace มี 1 datafile ขนาด 10M ขึ้นมาเพื่อทดสอบ
3. Connect เข้า HR แล้วลองวนลูปสร้าง table เพื่อให้ tablespace เต็ม
4. Enable RESUMABLE และตั้งเวลาไว้ 3600 วินาที (1 ชั่ืวโมง)
5. ลองสร้างเพิ่มอีก Table นึงจะดูเหมือนว่ามันแฮ้งค์และมีข้อมูลขึ้นมาใน Alert Log ด้วย
Sat Nov 22 23:35:02 2014
statement in resumable session 'User HR(85), Session 520, Instance 1' was suspended due to
ORA-01658: unable to create INITIAL extent for segment in tablespace KITTI_TBS
มันจะขึ้นใน EM ตรง Alert section ด้วย
6. จาก Admin user เราจะ Query DBA_RESUMABLE เพื่อดูข้อมูลเกี่ยวกับ session ที่ถูก suspend
7. DBA ได้เพิ่ม datafile เข้าไปที่ tablespace KITTI_TBS อีก 1 ไฟล์
เมื่อเพิ่มเข้าไปเสร็จแล้ว user HR สามารถทำ Operation ต่อได้โดยอัตโนมัติ ในที่นี้คือ Create Table
และ Alert Log ก็แจ้งข้อความว่า Statement ได้ถูก resume แล้ว
Sat Nov 22 23:49:49 2014
statement in resumable session 'User HR(85), Session 520, Instance 1' was resumed
8. Query DBA_RESUMABLE อีกครั้งเพื่อยืนยันว่า Operation resumable แล้ว
** ถ้ามี session ถูก suspend จะมีข้อมูลขึ้นมาใน V$SESSION_WAIT ที่คอลัมน์ EVENT ว่า "statement suspended, wait error to be cleared"
เราควรแจ้งเตือน User ด้วยวิธีการใดๆก็ได้ (เช่น Trigger ส่งอีเมล) เพื่อให้ User เข้าใจว่าเกิดเหตุการ Suspend ขึ้น
Ref : OCP Oracle 11g Administration II Exam Guide
สมัครสมาชิก:
บทความ (Atom)








































