دیتابیس اوراکل

دیتابیس اوراکل
طبقه بندی موضوعی

Cluster Time Management

سینک بودن تایم نودها در RAC یک امر حیاتی است. برای این موضوع میتوان از یکی از این 2 روش استفاده کرد:

1- فعالسازی یک time synchronization service مانند NTP یا Chrony

از OEL7 به بعد بهتر است از سرویس chrony بجای ntp استفاده شود. برای فعالسازی آن می­توان به روش زیر اقدام کرد:

# yum install -y chrony

# change /etc/chrony.conf

# systemctl enable chronyd

# systemctl start chronyd

# chronyc tracking

# chronyc sources –v

 

To quickly synchronize a server :

ntpdate 10.10.1.2

 

اگر میخواهید از سرویس NTP استفاده کنید میتوانید آن را به صورت زیر راه اندازی نمایید:

# yum install ntp

# vi /etc/ntp.conf --> add server IP iburst

# systemctl enable ntpd

# systemctl start ntpd

# systemctl status ntpd

# ntpq -p

 

2- فعالسازی Cluster Time Synchronization Service (CTSS)

اگر می­خواهید از CTSS برای سینک کردن تایم در کلاستر استفاده کنید، این سرویس باید در حالت Active باشد.  اگر ntp یا chrony فعال باشد (به این صورت که سرویسشان فعال باشد یا config file آن­ها موجود باشد)، CTSS به صورت پیش فرض با Observer mode بالا می­ آید و برای بردن آن به حالت Active باید سرویس های ntp یا chrony را غیرفعال نمایید.

$ crsctl check ctss

CRS-4700: The Cluster Time Synchronization Service is in Observer mode.

$crsctl stat res -t –init

ora.ctssd

1        ONLINE  ONLINE       test1-rac19c             OBSERVER:0,STABLE

 

Disable chronyd

# systemctl stop chronyd

# systemctl disable chronyd

بعد از اجرای این دستورات نباید config file مربوط به chrony (chrony.conf) در مسیر /etc وجود داشته باشد، اگر وجود داشت آن را تغییر نام دهید.

# ls -ltr /etc/chro*

-rw-r--r--. 1 root root   1079 Oct 12 13:36 /etc/chrony.conf

# cd /etc/

# mv chrony.conf chrony.conf.back

بعد از ریستارت کردن clusterware ،CTSS باید در حالت Active باشد:

$ crsctl check ctss

CRS-4701: The Cluster Time Synchronization Service is in Active mode.

CRS-4702: Offset (in msec): 0

 

$crsctl stat res -t –init

ora.ctssd

1        ONLINE  ONLINE       test1-rac19c             ACTIVE:0,STABLE

 

$ cluvfy comp clocksync -n all -verbose

Verifying Clock Synchronization ...

  Node Name                             Status

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

  test1-rac19c                          passed

  test2-rac19c                          passed

 

  Node Name                             State

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

  test2-rac19c                          Active

  test1-rac19c                          Active

 

  Node Name     Time Offset               Status

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

  test2-rac19c  0.0                       passed

  test1-rac19c  0.0                       passed

Verifying Clock Synchronization ...PASSED

 

Verification of Clock Synchronization across the cluster nodes was successful.

 

CVU operation performed:      Clock Synchronization across the cluster nodes

Date:                         Oct 14, 2020 2:22:12 PM

CVU home:                     /u01/app/grid/19.3.0/

User:                         oracle

 

ORA-00600: internal error code, arguments: [6965]

موقع ایمپورت یک جدول در دیتابیس (ورژن 19.10) که data type 2 تا از ستونهای آنها از نوع LONG بود با خطای زیر مواجه شدم:

ORA-31693: Table data object "RA"."TAB1" failed to load/unload and is being skipped due to error:

ORA-02354: error in exporting/importing data

ORA-39776: fatal Direct Path API error loading table "RA"."TAB1"

ORA-00600: internal error code, arguments: [6965], [19], [21], [], [], [], [], [], []

 

که طبق داکیومنت اوراکل (Document 2691467.1) وقتی tablespace را از حالت compress خارج کردم مشکل حل شد.

OLTP Table Compression is NOT supported for use with tables that have more than 255 columns or that have LONG data types.

 

ولی راه حل اصلی آن این است که ستونهای از نوع LONG به LOB تبدیل شوند.

طبق داکیومنت زیر، LONG فقط برای backward compatibility پشتیبانی میشود و بهتر است ستونهای از نوع LONG به LOB تبدیل شوند.

https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Data-Types.html#GUID-F6309DF8-162F-48A4-9454-FEE59EC6644F

EXPDP/IMPDP Of Partitioned Table

در مثال زیر از 2 پارتیشن جدول TEST1.TAB1 اکسپورت می­گیریم.

expdp SYSTEM

tables=TEST1.TAB1:P201201, TEST1.TAB1:P201202

dumpfile=EXP_TEST1_TAB1_%U.dmp

logfile=EXP_TEST1_TAB1.log

parallel=10

directory=DATA_PUMP_DIR

 

در مرحله بعد، پارتیشن هایی را که در مرحله قبل از آنها اکسپورت گرفتیم، در یک اسیکمای جدید با نام TEST2  ایمپورت میکنیم.

impdp SYSTEM

remap_schema=TEST1:TEST2

remap_tablespace=TBS_TEST1:TBS_TEST2

dumpfile=EXP_TEST1_TAB1_%U.dmp

logfile=IMP_TEST1_TAB1.log

directory=DATA_PUMP_DIR

transform=oid:n

parallel=10

exclude=STATISTICS,INDEX,CONSTRAINT,GRANT 

 

اگر از قبل یک اکسپورت full از جدول وجود دارد و در حال حاضر فقط به پارتیشنهای خاصی از آن جدول نیاز دارید، میتوانید ایمپورت را به صورت زیر انجام دهید.

impdp SYSTEM

remap_schema=TEST1:TEST2

tables=TEST1.TAB1:P201201,TEST1.TAB1:P201202

dumpfile=EXP_FULL_TEST1_%U.dmp

logfile=IMP_TEST1_TAB1.log

directory=DATA_PUMP_DIR

transform=oid:n

parallel=10

exclude=STATISTICS,INDEX,CONSTRAINT,GRANT

remap_tablespace=TBS_TEST1:TBS_TEST2

 

اگر میخواهید جدول را با یک نام جدید ایجاد کنید، میتوانید ایمپورت را به صورت زیر انجام دهید.

impdp SYSTEM

remap_schema=TEST1:TEST2

tables=TEST1.TAB1:P201201,TEST1.TAB1:P201202

remap_table=TEST1.TAB1:TAB1_NEW

dumpfile=EXP_FULL_TEST1_%U.dmp

logfile=IMP_TEST1_TAB1.log

directory=DATA_PUMP_DIR

transform=oid:n

parallel=10

exclude=STATISTICS,INDEX,CONSTRAINT,GRANT 

remap_tablespace=TBS_TEST1:TBS_TEST2

 

ORA-07445: exception encountered: core dump [lmmstrmlrg()+57]

DB Version:

19.10.0.0

 

Command:

impdp  \'/ as sysdba\' tables=USR.TEST1 directory=DIR1 dumpfile=expdp_2022-04-12.dmp logfile=impdp_2022-04-12.log encryption_password=password

 

Error:

ORA-07445: exception encountered: core dump [lmmstrmlrg()+57] [SIGSEGV] [ADDR:0x0] [PC:0x40E9C49] [Address not mapped to object] []

 

Cause:

Data Pump export is run using the following parameters, or Data Pump import of a file created with the following parameters is done:

     - encryption_mode

     - encryption_password

     - encryption_algorithm

 

Solution:

Upgrade to 19.14.0.0

 

Document:

Doc ID 32442404.8

 

Convert Non-CDB Database to PDB Database

 

Non-CDB Database Name

DB1

Non-CDB Database Version

19.12.0.0

Target CDB Database Name

CDB1

Target CDB Database Version

19.12.0.0

 

 

  1. In DB1:

SQL> SHUTDOWN IMMEDIATE;

SQL> STARTUP OPEN READ ONLY;

 

SQL> exec dbms_pdb.describe(pdb_descr_file => '/tmp/19cDB1.xml');

PL/SQL procedure successfully completed.

 

SQL> SHUTDOWN IMMEDIATE;

 

 

  1. In CDB1:

SQL> SET SERVEROUTPUT ON;

SQL> DECLARE

compatible CONSTANT VARCHAR2(3) := CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(pdb_descr_file => '/tmp/19cDB1.xml')

WHEN TRUE THEN 'YES'

ELSE 'NO'

END;

BEGIN

DBMS_OUTPUT.PUT_LINE(compatible);

END;

/

 

PL/SQL procedure successfully completed.

 

SQL> col cause for a20

SQL> col message for a35 word_wrapped

SQL> select cause, type, message, status from PDB_PLUG_IN_VIOLATIONS where name ='DB1';

 

 

CAUSE

TYPE

MESSAGE

STATUS

Parameter

WARNING

CDB parameter processes mismatch: Previous 5000 Current 6000

PENDING

Parameter

WARNING

CDB parameter sessions mismatch: Previous 7600 Current 9040

PENDING

Parameter

WARNING

CDB parameter db_files mismatch: Previous 2000 Current 1000

PENDING

 

 

SQL> CREATE PLUGGABLE DATABASE pdb1 USING '/tmp/19cDB1.xml'

  COPY

  FILE_NAME_CONVERT = ('+DATA', '+DATA2');

 

OR

 

SQL> CREATE PLUGGABLE DATABASE pdb1 USING '/tmp/19cDB1.xml'

  NOCOPY tempfile reuse;

 

 

SQL> alter session set container=PDB1;

SQL> @$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql

SQL> alter pluggable database PDB1 open;

SQL> show pdbs

 

CON_ID

CON_NAME                   

OPEN MODE

RESTRICTED

4

PDB1                               

READ WRITE

NO

 

 

 

Document:

https://oracle-base.com/articles/12c/multitenant-migrate-non-cdb-to-pdb-12cr1

https://dbaclass.com/article/convert-non-cdb-database-to-pdb-database-in-oracle-12c/

 

 

in SQL command '&'

برای حل مشکل '&' در کوئری های خود میتوانید به روشهای زیر عمل کنید:

Primary Query:

update b.otp a set a.token_type='s&online&offline' where a.user_id='7070';

 

In SQL*Plus:

SQL> set define off;

SQL> update b.otp a set a.token_type='s&online&offline' where a.user_id='7070';

 

In Toad:

update b.otp a set a.token_type='s&'||'online&'||'offline' where a.user_id='7070';

ORA-00600: internal error code, arguments: [ozip_header_read: corrupted hdr]

بعد از آپگرید از 12.2 به 19.11 ، خطای زیر را در alert log مشاهده کردیم:

ORA-00600: internal error code, arguments: [ozip_header_read: corrupted hdr], [], [], [], [], …

 

بعد از جستجو متوجه شدم که طبق Document زیر، این خطا مربوط به In-Memory میباشد:

Bug 22297022 - ORA-600:[ozip_header_read] after DML(update) and when in-memory is enabled (Doc ID 22297022.8)

در داکیومنت بالا گفته شده است که این باگ مربوط به دیتابیس هایی با ورژن کمتر از 12.2 است و از 12.2 به بعد این مورد حل شده است، ولی ما در ورژن 12.2 این مشکل را نداشتیم و بعد از آپگرید به دیتابیس 19.11 این خطا را گرفتیم.

با بررسی آبجکتهایی که In-Memory برای آنها فعال شده بود، متوجه شدم که مشکل از MATERIALIZED VIEWهایی است که In-Memory برای آنها enable شده است. که با disable کردن In-Memory برای آن MATERIALIZED VIEWها ، سپس مجددا enable کردن آن، مشکل حل شد.

alter materialized view TEST.MVIEW1 no inmemory;

alter materialized view TEST.MVIEW1 inmemory memcompress for capacity low priority high distribute auto for service default no duplicate;

Bitmap Based Count Distinct SQL Function

در محیط های Data Warehouse، استفاده از کوئری هایی که در آنها count(distinct) به کار برده شده است، متداول میباشد. همانطور که میدانید، یکی از راههای بالا بردن پرفرمنس کوئری هایی که در آنها از count(distinct) استفاده شده است، استفاده از Query Rewrite در Materialized Viewها است. به دو کوئری زیر توجه کنید:

SELECT promo_id, COUNT(DISTINCT prod_id)

  FROM sh.sales

GROUP BY promo_id

ORDER BY promo_id;

 

SELECT channel_id, COUNT(DISTINCT prod_id)

  FROM sh.sales

GROUP BY channel_id

ORDER BY channel_id;

 

 

 

 

 

 

 

 

 

 

اگر بخواهیم سرعت این کوئری ها را با Materialized View (Query Rewrite) افزایش دهیم، باید برای هر کدام از این کوئری ها یک Materialized View جداگانه ایجاد کنیم. ولی هدف ما در واقع باید این باشد که تعداد کمی Materialized View ایجاد کنیم و تا حد امکان از آنها در کوئری های مختلف استفاده کنیم. ولی تا قبل از اوراکل 19c این امکان برای ما وجود نداشت.

از Oracle 19c یک سری SQL functionها در رابطه با عملیات مرتبط با bitmapها اضافه شده اند، که این فانکشن ها، سرعت اجرایCOUNT(DISTINCT)  را در کوئری ها افزایش میدهند. طبق مطلبی که در داکیومنتهای اوراکل به آن اشاره شده است، تمرکز اصلی این فانکشن ها بر روی Materialized Viewهایی است که در آنها از aggregate data استفاده شده است.

این فانکشنها عبارتند از:

  • BITMAP_BIT_POSITION
  • BITMAP_BUCKET_NUMBER
  • BITMAP_CONSTRUCT_AGG
  • BITMAP_COUNT
  • BITMAP_OR_AGG

از این فانکشنها به صورتهای مختلفی میتوان استفاده کرد، یکی از موارد استفاده آن همانطور که در بالا هم به آن اشاره شد در  Materialized View (Query Rewrite) است که در زیر با ارائه یک مثال کاربرد آن توضیح داده شده است:

CREATE MATERIALIZED VIEW sh.mv_sales

ENABLE QUERY REWRITE

AS

      SELECT promo_id,

                    channel_id,

                    BITMAP_BUCKET_NUMBER (prod_id),

                    BITMAP_CONSTRUCT_AGG (BITMAP_BIT_POSITION (prod_id))

        FROM sh.sales

    GROUP BY promo_id, channel_id, BITMAP_BUCKET_NUMBER (prod_id);

 

 

 

 

 

 

 

 

 

 

حتما یک log برای Materialized View بالا ایجاد کنید:

CREATE MATERIALIZED VIEW LOG ON sh.sales

TABLESPACE users

WITH rowid;

 

 

 

 

در زیر کاربرد Materialized View بالا را در کوئری هایی که روی جدول sales زده میشود، مشاهده میکنیم:

  SELECT promo_id, COUNT (DISTINCT prod_id)

    FROM sh.sales

GROUP BY promo_id

ORDER BY promo_id;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  SELECT channel_id, COUNT (DISTINCT prod_id)

    FROM sh.sales

GROUP BY channel_id

ORDER BY channel_id;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Document:

https://docs.oracle.com/en/database/oracle/oracle-database/19/newft/new-features.html#GUID-9DBB57A5-9F40-49F1-80D7-78F1DFD62924

https://docs.oracle.com/pls/topic/lookup?ctx=en/database/oracle/oracle-database/19/newft&id=DWHSG-GUID-03107B3C-72D3-4B6B-A922-F13FF0CF2B6D

https://danischnider.wordpress.com/2019/04/20/bitmap-based-countdistinct-functions-in-oracle-19c/

Repairing SQL Failures with the SQL Repair Advisor

 

وقتی یک دستور SQL به یک critical error برخورد میکند و failed میشود، یکی از راهها این است که برای برطرف کردن خطای آن از SQL Repair Advisor کمک بگیریم. SQL Repair Advisor آن دستور SQL را آنالیز میکند و اگر بتواند برای برطرف کردن خطای پیش آمده یک patch ارائه میدهد. اگر شما آن patch را apply کنید، optimizer با جایگزین کردن یک plan جدید سعی میکند در اجراهای بعدی آن خطا را برطرف کند.

SQL Repair Advisor را از 2 طریق میتوان اجرا کرد:

1. Cloud Cntrol

2. DBMS_SQLDIAG package subprograms

 

Running the SQL Repair Advisor Using the DBMS_SQLDIAG Package Subprograms

با استفاده از subprogramهای پکیج DBMS_SQLDIAG میتوانیم SQL Repair Advisor را اجرا کنیم:

CREATE_DIAGNOSIS_TASK: ایجاد یک diagnostic task

EXECUTE_DIAGNOSIS_TASK: اجرای diagnostic task که در مرحله قبل ایجاد شده است.

ACCEPT_SQL_PATCH: اگر در مرحله قبل patch پیشنهاد شده باشد، با استفاده از این subprogram میتوان آن patch را apply کرد.

نکته مهم: از اوراکل 19c میتوان بجای استفاده از سه subprogram بالا، تنها با استفاده از یک subprogram با نام SQL_DIAGNOSE_AND_REPAIR همه کارهای بالا را انجام داد.

مراحل استفاده از DBMS_SQLDIAG:

1- ایجاد یک diagnosis task با نام error_task

DECLARE

  rep_out   CLOB;

  t_id      VARCHAR2(50);

BEGIN

  t_id := DBMS_SQLDIAG.CREATE_DIAGNOSIS_TASK (

           sql_text => 'DELETE FROM t t1

                        WHERE t1.a = ''a'' AND

                              ROWID <> (SELECT MAX(ROWID)

                                        FROM t t2

                                        WHERE t1.a = t2.a AND

                                              t1.b = t2.b AND

                                              t1.d = t2.d)',

           task_name => 'error_task',

           problem_type => DBMS_SQLDIAG.PROBLEM_TYPE_COMPILATION_ERROR);

END;

 

2- اجرای error_task:

DBMS_SQLDIAG.EXECUTE_DIAGNOSIS_TASK ('error_task');

 

3- تولید report برای error_task:

DECLARE

    rep_out   CLOB;

BEGIN

    rep_out :=

        DBMS_SQLDIAG.report_diagnosis_task ('error_task', DBMS_SQLDIAG.type_text);

    DBMS_OUTPUT.put_line ('Report : ' || rep_out);

END;

 

4- apply کردن patch در صورت وجود:

SQL Patch شبیه SQL Profile است با این تفاوت که برخلاف SQL Profile برای رفع خطاهای compilation و execution استفاده میشود.

EXECUTE DBMS_SQLDIAG.ACCEPT_SQL_PATCH(task_name => 'error_task', task_owner => 'SYS', replace => TRUE);

 

میتوانید با استفاده از Cloud Control و subprogramهای ALTER_SQL_PATCH و DROP_SQL_PATCH در پکیج DBMS_SQLDIAG، اقدام به حذف کردن و یا disable کردن patchهای ایجاد شده نمایید.

5- اجرای مجدد آن دستور sql و تست patch ایجاد شده

 

نکته: با استفاده از پکیج DBMS_SQLDIAG میتوانید از patch ایجاد شده در یک دیتابیس export بگیرید و در یک دیتابیس دیگر import کنید.

 

Create LVM in Oracle Linux

1- lsblk

 

 

 

 

 

 

 

 

2- fdisk /dev/sda (add a new partition)

3- pvcreate /dev/sda4

4- pvscan

5- pvdisplay

6- pvs

7- vgcreate vg_bk /dev/sda4

8- vgdisplay

9- vgs

10- lvcreate -l 100%FREE -n backup vg_bk (OR lvcreate -L 500G -n backup vg_bk)

11- lvs

12- mkfs.xfs /dev/vg_bk/backup

13- lsblk

14- mkdir /BK

15- mount  /dev/vg_bk/backup /BK

16- chown -R oracle:oinstall /BK

17- chmod -R 775 /BK

18- df -h