Vấn đề: Đối với các bảng dữ liệu có đánh partition theo tháng hoặc theo ngày, người DBA thường xuyên phải đánh partition, nếu quên dữ liệu insert vào sẽ bị lỗi và có thể dẫn đến lỗi toàn hệ thống.
– Giải pháp: Để giải quyết vấn đề trên ta thường viết thủ tục đánh partition tự động cho bảng và đặt scheduler để chạy định kỳ. Việc đánh partition không ảnh hưởng tới các thao tác insert, select, update, delete.
– Ý tưởng: Để đảm bảo có thể đánh partition một cách tự động ta phải đặt tên partition theo một số quy ước:
+ Trong tên partition phải chứa thông tin về ngày tháng của dữ liệu
+ Phần đầu của tên partition phải giống nhau
– Dựa vào thông tin partition trong tên ta xác định thời gian cần đánh partition tiếp theo
Thủ tục thực hiện:
1. Tạo thủ tục
create PROCEDURE proc_create_partition
IS
CURSOR c_partition
IS
SELECT owner,object_name,
MAX (SUBSTR (subobject_name,
LENGTH (subobject_name) - 5,
LENGTH (subobject_name)
)
) AS sub_partition
FROM dba_objects
WHERE owner='APP_OWNER' and object_type = 'TABLE PARTITION'
AND object_name NOT LIKE 'BIN$%'
--- AND object_name NOT IN ('TAB1')
GROUP BY object_name;
v_loop_str VARCHAR (3000);
v_date DATE;
p_error VARCHAR (2000);
BEGIN
FOR v_partition IN c_partition
LOOP
v_date := TO_DATE (v_partition.sub_partition, 'yyMMdd');
WHILE v_date <=
ADD_MONTHS (TO_DATE (v_partition.sub_partition, 'yyMMdd'), 1)
LOOP
BEGIN
v_date := v_date + 1;
v_loop_str := '';
v_loop_str :=
'alter table ' || v_partition.owner ||'.'
|| v_partition.object_name
|| ' add partition DATA20'
|| TO_CHAR (v_date, 'yyMMdd')
|| ' values less than (to_date(''20'
|| TO_CHAR (v_date, 'yyMMdd')
|| ''',''yyyyMMdd''))';
DBMS_OUTPUT.put_line (v_loop_str);
EXECUTE IMMEDIATE v_loop_str;
v_loop_str := '';
EXCEPTION
WHEN OTHERS
THEN
p_error := 'Loi xay ra khi them partition: ' || SQLERRM;
DBMS_OUTPUT.put_line (p_error);
END;
END LOOP;
END LOOP;
END;
2. Tạo scheduler job:
Chạy thủ tục kia hàng ngày lúc 01h00