Mục lục

1. Giới thiệu

Để chuyển đổi 1 bảng bình thường (non-partition) sang bảng partition, chúng ta có thể có nhiều cách.

Trong bài viết này tôi sẽ hướng dẫn các bạn cách sử dụng thủ tục DBMS_REDEFITION để thực hiện điều này nhé.

Cách làm này có ưu điểm lớn nhất là:

Trong quá trình chuyển đổi bảng từ non-partition sang partition, bạn vẫn thao tác select, insert, update, delete bình thường, như không có gì xảy ra!

Chú ý: Cách làm này chỉ áp dụng với các bảng không thuộc sở hữu của user SYS thôi nhé.

Liên quan đến chủ đề partitioned table, nếu bạn chưa biết nó là gì, có thể tham khảo bài viết sau của tôi:

Đọc thêm  Kiến thức cơ bản về partition table

2. Cách làm

1. Tạo môi trường test:

Tạo bảng INVOICES là bảng non-partition

CREATE TABLE DUY.INVOICES
(invoice_no    NUMBER PRIMARY KEY,
 invoice_date  DATE   NOT NULL,
 comments      VARCHAR2(500));

Thêm 1 chút dữ liệu để test

INSERT INTO DUY.INVOICES VALUES (1, '01-Mar-2021', 'Quarter 1');
INSERT INTO DUY.INVOICES VALUES (2, '11-Jul-2021', 'Quarter 2');
INSERT INTO DUY.INVOICES VALUES (3, '15-Sep-2021', 'Quarter 3');
INSERT INTO DUY.INVOICES VALUES (4, '21-Nov-2021', 'Quarter 4');
COMMIT;

Tạo bảng INVOICES2 là bảng partition với các cột và data type giống hệt INVOICES, nhưng bảng INVOICES2 là bảng partition

CREATE TABLE invoices2
(invoice_no    NUMBER PRIMARY KEY,
 invoice_date  DATE   NOT NULL,
 comments      VARCHAR2(500))
PARTITION BY RANGE (invoice_date)
(PARTITION invoices_q1 VALUES LESS THAN (TO_DATE('01/04/2021', 'DD/MM/YYYY')),
 PARTITION invoices_q2 VALUES LESS THAN (TO_DATE('01/07/2021', 'DD/MM/YYYY')),
 PARTITION invoices_q3 VALUES LESS THAN (TO_DATE('01/09/2021', 'DD/MM/YYYY')),
 PARTITION invoices_q4 VALUES LESS THAN (TO_DATE('01/01/2022', 'DD/MM/YYYY')));

2. Kiểm tra xem có thể dùng DBMS_REDEFINITION được hay không

BEGIN
   SYS.DBMS_REDEFINITION.can_redef_table (
      uname          => 'DUY',
      tname          => 'INVOICES',
      options_flag   => DBMS_REDEFINITION.CONS_USE_ROWID);
END;
/

Nếu kết quả không xuất hiện lỗi gì, có output như sau thì có nghĩa là bảng INVOICES có thể áp dụng DBMS_REDEFINITION để chuyển dữ liệu sang bảng INVOICES2 được.

PL/SQL procedure successfully completed.

3. Bắt đầu đồng bộ dữ liệu 

Quá trình đồng bộ dữ liệu có thể kéo dài rất lâu. Bạn nên thực hiện các câu lệnh sau để tăng luồng xử lý, tăng tốc độ đồng bộ:

ALTER SESSION FORCE PARALLEL DML PARALLEL 16;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 16;

Sau đó, bạn thực hiện câu lệnh sau:

BEGIN
   SYS.DBMS_REDEFINITION.start_redef_table (uname        => 'DUY',
                                            orig_table   => 'INVOICES',
                                            int_table    => 'INVOICES2');
END;
/

Thủ tục DBMS_REDEFINITION sẽ bắt đầu chuyển dữ liệu hiện có tại INVOICES sang INVOICES2.

4. Copy các đối tượng liên quan đến bảng sang bảng mới

Thủ tục dưới đây sẽ copy các index, trigger, constraint, privileges trên bảng gốc và chuyển sang bảng mới.

DECLARE
  num_errors PLS_INTEGER;
BEGIN
  DBMS_REDEFINITION.copy_table_dependents(
    uname             => 'DUY',
    orig_table        => 'INVOICES',
    int_table         => 'INVOICES2',
    copy_indexes      => DBMS_REDEFINITION.cons_orig_params,
    copy_triggers     => TRUE, 
    copy_privileges   => TRUE, 
    ignore_errors     => FALSE,
    num_errors        => num_errors); 
END;
/

5. Đồng bộ dữ liệu sinh ra trong quá trình chuyển đổi

Bạn thực hiện thủ tục sau để đồng bộ những dữ liệu mới được sinh ra trong khoảng thời gian chuyển dữ liệu này sang bảng mới

BEGIN
   DBMS_REDEFINITION.sync_interim_table (uname        => 'DUY',
                                         orig_table   => 'INVOICES',
                                         int_table    => 'INVOICES2');
END;
/

6. Kết thúc quá trình đồng bộ

Bạn thực hiện câu lệnh sau để kết thúc toàn bộ thủ tục chuyển đổi:

BEGIN
   DBMS_REDEFINITION.finish_redef_table (uname        => 'DUY',
                                         orig_table   => 'INVOICES',
                                         int_table    => 'INVOICES2');
END;
/

Ở bước này bảng INVOICES2 và INVOICE sẽ tráo đổi tên cho nhau. 

Như vậy, bảng INVOICES lúc này sẽ là bảng partition. Còn bảng INVOICES2 lại là bảng non-partition.

 

3. Kiểm tra lại:

1. Kiểm tra kiểu của bảng là non-partition hay partition

select table_name, PARTITIONED from dba_tables where owner='DUY';

Kết quả là:

TABLE_NAME    PARTITIONED
-----------   -----------
INVOICES2     NO
INVOICES      YES

2. Kiểm tra dữ liệu của bảng có đầy đủ hay không

select * from duy.invoices;

Kết quả:

INVOICE_NO INVOICE_D COMMENTS
---------- --------- ------------------------------
         1 01-MAR-21 Quarter 1
         2 11-JUL-21 Quarter 2
         3 15-SEP-21 Quarter 3
         4 21-NOV-21 Quarter 4

Như vậy tôi đã hướng dẫn các bạn chuyển đổi 1 bảng non-partition sang partition bằng phương pháp DBMS_REDEFINITION.

Hẹn gặp lại các bạn vào các bài viết tiếp theo.

Bạn có thể xem phiên bản youtube của bài viết tại đây:

Nguồn: https://dangxuanduy.com/

Hiện tại, tôi có tổ chức đều đặn các khóa học về quản trị Oracle Database, tôi sẽ để thông tin ở đây, để bạn nào quan tâm về lịch học cũng như chương trình học có thể theo dõi nhé.

KHOÁ DÀNH CHO NGƯỜI MỚI

KHÓA HỌC: QUẢN TRỊ ORACLE DATABASE THẬT LÀ ĐƠN GIẢN (ADMIN 1)

CÁC KHOÁ NÂNG CAO:

KHÓA HỌC ORACLE NÂNG CAO: QUẢN TRỊ KIẾN TRÚC MULTITENANT 12c

KHÓA HỌC ORACLE NÂNG CAO: QUẢN TRỊ HỆ THỐNG DATA GUARD

CÁC KHOÁ COMBO:

COMBO 1: ADMIN 1 + MULTITENANT 12c

COMBO 2: ADMIN 1 + DATA GUARD

COMBO 3: ADMIN 1 + MULTITENANT 12c + DATA GUARD

LỊCH HỌC:

Mời bạn xem tại đây: LỊCH HỌC CÁC LỚP ORACLE 

ĐĂNG KÝ:

https://forms.gle/MtCAoRQFenP886y79

Hãy tham gia group “Kho tài liệu kiến thức database” để cùng học hỏi và chia sẻ nhé.

0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Phản hồi nội tuyến
Xem tất cả bình luận
0
Rất thích suy nghĩ của bạn, hãy bình luận.x