แสดงบทความที่มีป้ายกำกับ ora- แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ ora- แสดงบทความทั้งหมด

วันอังคารที่ 12 พฤษภาคม พ.ศ. 2552

จำนวน datafile ที่สามารถสร้างได้ บน Oracle ดาต้าเบส

ผู้ดูแลจะไม่พบปัญหา จนต้องตอบคำถามเกี่ยวกับจำนวน datafile บนดาต้าเบสที่ไม่ใหญ่มากนัก
แต่หากดาต้าเบสมีขนาดใหญ่ จนต้องใช้จำนวน tablespace มากๆ มันเริ่มจะมีคำถามกลับมาที่จำนวนของ datafile ที่จะสร้างได้ในดาต้าเบส

ผู้ดูแลดาต้าเบสสามารถที่จะหาจำนวนของ datafile ที่จะสามารถสร้างบนดาต้าเบส ได้จาก DB_FILES พารามิเตอร์

SQL> show parameter db_files

NAME TYPE VALUE
----------------------
db_files integer 200
จากตัวอย่าง สามารถสร้าง datafile ได้ที่ 200 ไฟล์
แต่ทั้งนี้ต้องขึ้นกัน Operation System (การจำกัดจำนวนไฟล์บน OS) ด้วย... ซึ่งจะเจอได้น้อยมาก

หากมีการสร้าง datafile ที่มากกว่าค่า db_files พารามิเตอร์ แน่นอนจะทำให้ผู้ดูแลรู้จัก ORA Error มากขึ้นอีกตัว

SQL> create tablespace a01 datafile '+DATA1' size 20M;
create tablespace a01 datafile '+DATA1' size 20M
*
ERROR at line 1:
ORA-00059: maximum number of DB_FILES exceeded
อย่างไรก็ตาม ผู้ดูแลสามารถที่จะเพิ่มค่า DB_FILES พารามิเตอร์
แต่ต้อง restart ดาต้าเบส...
ในเคสที่ใช้ Oracle RAC ผู้ดูแลต้อง shutdown ทุก node (shutdown ดาต้าเบส นั่นเอง... ไม่สามารถ restart ทีละnode)

ค่า db_files เท่าไหร่... ถึงจะเป็นค่าที่เหมาะสม
นั่นเป็นสิ่งที่ผู้ดูแลต้องคิดและตอบโจทย์ เพราะมันผูกกับการจำกัดจำนวนไฟล์บน OS... แล้วยังใช้ SGA memory ในการเก็บข้อมูล datafile ด้วย

หลายคนที่ใช้ Oracle ดาต้าเบส คงมีคำถามว่า... แล้ว MAXDATAFILES บน controlfile ??? ...ยังมีผลเกี่ยวข้องหรือไม่
แน่นอน! ถ้าคุณใช้ Oracle 8i หรือสูงกว่า ค่า MAXDATAFILES บน controlfile จะการขยายโดยอัตโนมัติ... เมื่อมีการเพิ่มจำนวน datafile เกินค่า MAXDATAFILES แต่น้อยกว่าหรือเท่ากับค่า db_files (metalink: 331067.1)

ตัวอย่างการเพิ่ม db_files พารามิเตอร์ (เมื่อใช้ spfile)
SQL> show parameter db_files

NAME TYPE VALUE
----------------------
db_files integer 200

SQL> alter system set set db_files=500 scope=spfile;

SQL> shutdown immediate

SQL> startup

SQL> show parameter db_files

NAME TYPE VALUE
----------------------
db_files integer 500
การเปลี่ยนค่า db_files ไม่ใช่ปัญหา ถ้าระบบสามารถหยุดการใช้งาน
สิ่งที่ยากยิ่งกว่า คือการกำหนดค่า ว่าในเวลาหนึ่งปี หรือสองปี ต้องใช้จำนวน datafile เท่าไหร่

วันอังคารที่ 5 พฤษภาคม พ.ศ. 2552

การลดขนาด (oracle) database segment ออนไลน์

ตั้งแต่ oracle 10g เราสามารถออนไลน์ลดขนาด(shrink) segment เพื่อให้ได้พื้นที่ว่าง ส่งผลให้เกิดประสิทธิภาพกับการเก็บข้อมูล พร้อมกันนี้ยังช่วยลด High Water Mark (HWM)
อย่างไรก็ตามวิธีนี้ใช้ได้กับ tablespace ที่เป็น Locally Manage และ Automatic Segment Space Management (ASSM)

การลดขนาด(shrink) segment สามารถทำได้ทั้ง TABLE และ INDEX แต่อย่างไรก็ตามเราต้อง enable row movement บน TABLE เสียก่อน
การ enable/disable row movement คำสั่งนี้สามารถทำให้ package/procedure/function ที่ผูกกับ table นี้ invalid ได้

SQL> create table temp (id number);

Table created.

SQL> alter table temp shrink space;
alter table temp shrink space
*
ERROR at line 1:
ORA-10636: ROW MOVEMENT is not enabled


SQL> alter table temp enable row movement;

Table altered.

SQL> alter table temp shrink space;

Table altered.
การใช้คำสั่ง shrink เพื่อลดขนาด segment นั้น...
ALTER TABLE...SHRINK ช่วยบีบขนาดพื้นที่ของข้อมูล และลด HWM, ถ้า SHRINK SPACE COMPACT ช่วยบีบอัดข้อมูล แต่ HWM ไม่ได้เปลี่ยนแปลง, แต่... ถ้าเรา SPACE CASCADE มันจะกระทำกับ object ที่เกี่ยวข้องด้วย

การ shrink นี้ แน่นอนสามารถใช้กับ table, index (b-tree,bit-mapped) และ object บางปรเภท
เราสามารถหาข้อมูลได้จาก Oracle Document

อีกประเด็นเกี่ยวกับการ shrink ในระหว่างที่เรา shrink, ROWID อาจจะมีการเปลี่ยนแปลง เมื่อเราย้ายข้อมูลระหว่าง block ดังนั้นก็แน่นอนอีกนั่นแหละว่า เราไม่สามารถ shrink กับ materialized view ที่ใช้ rowid และเราต้อง enable row movement

อะไรที่เราต้องกังวลเมื่อทำการลดขนาด segment ด้วยวิธีนี้, การ lock ข้อมุลในระหว่างที่กระทำการ shrink นั้นจะเป็นในระดับ row หรือ ข้อมูลใน block ที่ถูกย้าย แน่นอนมันให้ lock บน DML ที่เป็น update/delete... ในขณะที่ HWM มีการปรับเปลี่ยนจะส่งผลให้เกิด lock ในระดับ exclusive จนปรับเปลี่ยนสำเร็จ

สำหรับ index(ไม่ทำให้ unusable)ไม่มีผลกระทบ

ในบางขณะเวลา เราอาจจำเป็นที่จะต้องแบ่งงานออก เป็นสองขั้นตอน โดยการ SHRINK SPACE COMPACT จากนั้น SHRINK SPACE ตามทีหลัง

SQL> alter table temp shrink space compact;

Table altered.

SQL> alter table temp shrink space;

Table altered.
การหาพื้นที่ว่างกับ TABLE บางครั้งเราคิดถึง ALTER TABLE...MOVE
แต่... ถ้าใช้ tablespace ที่เป็น ASSM ลอง ALTER TABLE...SHRINK มันอาจจะช่วยได้

วันอาทิตย์ที่ 16 พฤศจิกายน พ.ศ. 2551

ใช้ "UPDATE GLOBAL INDEXES" "UPDATE INDEXES"

เมื่อเรามี การ add/move/split ... อะไรก็ตามที่ กระทำให้ data มีการเปลี่ยน partitions indexes:
เราควรสนใจ option: "UPDATE GLOBAL INDEXES" with global "UPDATE INDEXES" with local

นี่เป็นตัวอย่าง คร่าวๆ กับ hash table + gloabal index
CREATE TABLE TEMP_PAR01
     (no NUMBER,
      data VARCHAR2 (50))
   PARTITION BY HASH (no)
   PARTITIONS 5;


CREATE INDEX temp01_global_par_idx ON temp_par01(no)
GLOBAL PARTITION BY hash(no)
PARTITIONS 5;

alter table temp_par01 add partition p6;

analyze table temp_par01 compute statistics;

ไม่พบ error ใดๆ ทั้งสิ้นเพราะยังไม่มีข้อมูล

ใส่ข้อมูลเพื่อทดสอบ:

begin

 for x in 1 .. 1000 

  loop 

   insert into TEMP_PAR01 (no) values (x);

  end loop;

end;

/

commit;

ลอง เพิ่ม partition อีกครั้ง

alter table temp_par01 add partition p7;

analyze table temp_par01 compute statistics;
analyze table temp_par01 compute statistics
*
ERROR at line 1:
ORA-01502: index 'SCOTT.TEMP01_GLOBAL_PAR_IDX' or partition of such index is in unusable state

พบว่า partitions indexes กลายเป็น unusable state

select partition_name, status  from user_ind_partitions 
where index_name='TEMP01_GLOBAL_PAR_IDX';

PARTITION_NAME                 STATUS
------------------------------ --------
SYS_P62                        UNUSABLE
SYS_P63                        UNUSABLE
SYS_P64                        UNUSABLE
SYS_P65                        UNUSABLE
SYS_P61                        UNUSABLE

ดังนั้นลองใช้ "UPDATE GLOBAL INDEXES"

Use "UPDATE GLOBAL INDEXES" with global "UPDATE INDEXES" with local 


alter table temp_par01 add partition p8 UPDATE GLOBAL INDEXES;

analyze table temp_par01 compute statistics;

ไม่เจอ error:

select partition_name, status  from user_ind_partitions where index_name='TEMP01_GLOBAL_PAR_IDX';

PARTITION_NAME                 STATUS
------------------------------ --------
SYS_P62                        USABLE
SYS_P63                        USABLE
SYS_P64                        USABLE
SYS_P65                        USABLE
SYS_P61                        USABLE

สรุปได้ว่า ขณะที่มีการ เพิ่ม partition tables ก็ได้มีการ update ที่ indexes ด้วย
ข้อดีตรงนี้ ช่วยให้เรามั่นใจ ได้ว่า indexes ที่้ใช้กลายเป็น unusable state

อย่างไร เมื่อมีการกระทำกับ partitions tables อย่าลืม check status ของ partitions indexes ด้วย 

 ถ้าพบ unusable state ก็ทำการ rebuild partitions indexes นั้นๆไป 

ALTER INDEX  &lt index_name &gt REBUILD PARTITION &lt partition_name&gt 


วันจันทร์ที่ 1 กันยายน พ.ศ. 2551

ORA-00312: online log 1 thread 1 ... and resolve for Today

Oracle TEST
V. 11.1.0.6.0

ไม่สามารถ start database


SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-16038: log 1 sequence# 100 cannot be archived
ORA-19502: write error on file "", block number (block size=)
ORA-00312: online log 1 thread 1: '/oradata/testdb2/redo01.log'

ดังนั้น recover database:

SQL> recover database until cancel;
Media recovery complete.

SQL> ALTER DATABASE OPEN RESETLOGS;

วันจันทร์ที่ 19 พฤษภาคม พ.ศ. 2551

ตัวอย่าง ORA-00313 เมื่อบาง member ใน group ถูกลบ

SQL> alter database add logfile member '/tmp/redo033.log' to group 3;

Database altered.

SQL> ho
$ ls -la /tmp/redo033.log
-rw-r----- 1 oracle oinstall 52429312 May 19 17:13 /tmp/redo033.log


SQL> select * from v$log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------
1 1 436 52428800 2 YES ACTIVE 32611337 19-MAY-08
2 1 437 52428800 2 NO CURRENT 32611361 19-MAY-08
3 1 435 52428800 3 YES INACTIVE 32611335 19-MAY-08


$ rm /tmp/redo033.log

SQL> alter system switch logfile;
-----------
NO ERROR:
-----------

Check alert log:

Errors in file testdb_arc0_25296.trc:
ORA-00313: open failed for members of log group 3 of thread 1
ORA-00312: online log 3 thread 1: '/tmp/redo033.log'
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory


SQL> alter database drop logfile member '/tmp/redo033.log';

Database altered.

SQL> alter database add logfile member '/tmp/redo033.log' to group 3;

Database altered.


------------------------------


SQL> select * from v$log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------
1 1 463 52428800 2 YES ACTIVE 32612535 19-MAY-08
2 1 462 52428800 2 YES ACTIVE 32612521 19-MAY-08
3 1 464 52428800 3 NO CURRENT 32612545 19-MAY-08

SQL> ho

$ rm /tmp/redo033.log


SQL> alter system switch logfile;
-----------
NO ERROR:
-----------

Check alert log:
Errors in file testdb_m000_14312.trc:
ORA-00313: open failed for members of log group 3 of thread 1
ORA-00312: online log 3 thread 1: '/tmp/redo033.log'
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
Thread 1 cannot allocate new log, sequence 466


SQL> alter database drop logfile member '/tmp/redo033.log';

Database altered.

SQL> alter database add logfile member '/tmp/redo033.log' to group 3;

Database altered.

--------------------------------