بررسی common user در محیط Multitenant

با ارائه ویژگی multitenant در اوراکل 12c، نوع دیگری از کاربر به نام common user ارائه شد که در محیط cdb قابل ایجاد می باشد و همچنین در صورت دارا بودن مجوز لازمه، به pdbهای مختلف، امکان دسترسی خواهد داشت. کاربرد عمده این نوع از کاربر، در انجام عملیات مدیریتی می باشد و معمولا مالک اشیای حاوی اطلاعات کاربر نخواهد بود.

نکته: علاوه بر common user، نوع دیگری از کاربر هم در محیط multitenant وجود دارد که تنها در محیط pdb قابل ایجاد می باشد این نوع از کاربرها، به local user معروف هستند و خصوصیتهایی را مشابه با کاربران حاضر در محیط non-cdb دارند.

به طور کلی دو نوع از common user در بانک موجود یا قابل ایجاد می باشند نوع اول انها همانند sys، system و … توسط اوراکل و در زمان ایجاد بانک ساخته شده(ORACLE_MAINTAINED=Y) و نوع دوم هم بعد از ساخت بانک قابل ایجاد می باشند(ORACLE_MAINTAINED=N).

در این متن، به طور مختصر، به تعدادی از مسائل و چالشهای مربوط به نوع دوم از common userها خواهیم پرداخت.

برای تفکیک اسامی common user(نوع دوم) از local user، اسامی آنها با پیشوند c## شروع می شوند(به طور پیش فرض):

 SQL> create user c##usef identified by usef;

User created.

که این پیشوند از طریق پارامتر COMMON_USER_PREFIX تعیین می شود:

 SQL> show parameter COMMON_USER_PREFIX

NAME                          VALUE

————————— ———-

common_user_prefix   C##

همچنین امکان تغییر این پیشوند از طریق تغییر مقدار پارامتر common_user_prefix وجود دارد. برای مثال، در دستور زیر، مقدار این پارامتر را به common_ تغییر می دهیم:

 SQL> alter system set common_user_prefix=common_ scope=spfile;

System altered.

بعد از این تغییر، common userها باید با پیشوند common_ ایجاد شوند:

 SQL> create user common_usef identified by usef;

User created.

همچنین حذف کامل پیشوند برای این نوع از کاربران امکان پذیر می باشد:

 SQL> alter system set common_user_prefix=” scope=spfile;

System altered.

در این صورت می توان اسامی common userها را بدون پیشوندی مشخص، و مشابه با local user ایجاد کرد:

SQL> create user usef identified by a;

User created.

با این دستور، نام کاربر usef در لیست common userها قابل مشاهده می باشد:

SQL>  select USERNAME,COMMON,CON_ID,ORACLE_MAINTAINED from cdb_users where USERNAME=’USEF’;

USERNAME   COM     CON_ID O

———- — ———- –

USEF       YES          1 N

البته انجام این کار، باید با ملاحضاتی هم همراه باشد برای مثال در صورت وجود کاربر usef در یک pdb، نباید کاربری با این نام در محیط cdb ایجاد کرد. این کار باعث بروز خطا در محیط pdb خواهد شد. مثال زیر را ببینید.

مثال) برای شبیه سازی این مسئله، در ابتدا کاربری را با نام usef در محیط pdb ایجاد می کنیم:

 SQL> alter session set container=pdb18c;

Session altered.

 SQL> create user usef identified by a;

User created.

در صورتی که pdb مورد نظر، در حالت read write قرار داشته باشد، ایجاد کاربر عمومی usef، با خطا مواجه خواهد شد(در اوراکل 18c):

 SQL>  alter session set container=cdb$root;

Session altered.

 SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED

———- —————————— ———- ———-

2 PDB$SEED                       READ ONLY  NO

5 PDB18C                         READ WRITE NO

  SQL> create user usef identified by a container=all;

ORA-01920: user name ‘USEF’ conflicts with another user or role name

SQL> create user usef identified by a;

ORA-01920: user name ‘USEF’ conflicts with another user or role name

با بستن pdb18c، این خطا برطرف خواهد شد:

 SQL> alter pluggable database PDB18C close;

Pluggable database altered.

 SQL> create user usef identified by a container=all;

User created.

با اجرای این دستور، دو کاربر عمومی و محلی با نام مشترک usef در بانک موجود خواهند بود که مشکلاتی را در سطح pdb ایجاد خواهند کرد. برای مثال، باز شدن مجدد pdb همراه با خطا و به صورت RESTRICTED خواهد بود:

 SQL>  alter pluggable database PDB18C open;

Warning: PDB altered with errors.

 SQL> show pdbs

CON_ID CON_NAME                       OPEN MODE  RESTRICTED

———- —————————— ———- ———-

2 PDB$SEED                       READ ONLY  NO

5 PDB18C                         READ WRITE YES

همچنین pdb18c کاربر usef را به عنوان local user خواهد شناخت:

 SQL> alter session set container=PDB18C;

Session altered.

 SQL>  select USERNAME,COMMON,CON_ID,ORACLE_MAINTAINED from cdb_users where USERNAME=’USEF’;

USERNAME   COM     CON_ID O

———- — ———- –

USEF       NO           5 N

برای حل محدودیت ایجاد شده، می توان کاربر عمومی usef را حذف کرد:

 SQL> alter session set container=cdb$root;

Session altered.

 SQL> drop user usef;

User dropped.

 SQL> alter pluggable database PDB18C close;

Pluggable database altered.

 SQL> alter pluggable database PDB18C open;

Pluggable database altered.

 SQL> show pdbs    CON_ID

CON_NAME                       OPEN MODE  RESTRICTED

———- —————————— ———- ———-

2 PDB$SEED                       READ ONLY  NO

5 PDB18C                         READ WRITE NO

 

*ایجاد common user از نوع اول(که در ابتدا متن، مطالبی در مورد آن اورده شد: Oracle-supplied administrative)، با کمک پارامتر _oracle_script و بدون تعیین پیشوندی خاص قابل انجام می باشد:

 

SQL> show parameter common

common_user_prefix                   string      c##

SQL> alter session set “_ORACLE_SCRIPT”=true;

Session altered.

SQL> create user esfandiar identified by a;

User created.

SQL> alter session set “_ORACLE_SCRIPT”=false;

Session altered.

 

کاربر عمومی اسفندیار مانند کاربرانی که توسط اوراکل ایجاد و نگهداری می شوند، به حساب خواهد امد همانند کاربر sys، system و … به همین دلیل، فیلد ORACLE_MAINTAINED در ویوی cdb_users برای این کاربر برابر با yes می باشد:

SQL> select USERNAME,COMMON,CON_ID,ORACLE_MAINTAINED from cdb_users where USERNAME=’ESFANDIAR’;

USERNAME         COM     CON_ID O

———-               — ———- –

ESFANDIAR         YES          1 Y

همچنین امکان حذف این کاربر، بدون کمک پارامتر _oracle_script میسور نخواهد بود:

SQL> drop user esfandiar;

ORA-28014: cannot drop administrative users

SQL> alter session set “_ORACLE_SCRIPT”=true;

Session altered.

SQL>  drop user esfandiar;

User dropped.

SQL>  alter session set “_ORACLE_SCRIPT”=false;

Session altered.

common user و مجوزها

common userها می توانند در هر pdb، مجوز متفاوتی داشته باشند:

SQL> create user c##usef identified by a;

User created.

SQL> alter session set container=PDB18C;

Session altered.

SQL>  grant create session to c##usef;

Grant succeeded.

SQL> alter session set container=PDBCLONE;

Session altered.

SQL> revoke create session from c##usef;

ORA-01952: system privileges not granted to ‘C##USEF’

همچنین می توان با کمک عبارت container در زمان اهدای مجوز به این نوع از کاربران(در سطح cdb)، مجوز مورد نظر را به این کاربر در سطح تمامی pdbها اعمال نمود. اهدای مجوز dba به c##usef در همه pdbها:

SQL> alter session set container=cdb$root;

Session altered.

SQL> grant dba to c##usef container=all;

Grant succeeded.

 

با اهدای این مجوز، امکان revoke کردن آن در سطح یک pdb وجود نخواهد داشت:

 

SQL> alter session set container=PDB18C;

Session altered.

SQL> revoke create session from c##usef;

ORA-65092: system privilege granted with a different scope to ‘C##USEF’

سوییچ بین containerها با مجوز set container

کاربر c##usef با دارا بودن مجوز create session، امکان استفاده از دستور set container را دارد؟

پاسخ این سوال را در ادامه ببینید:

SQL> grant create session to c##usef container=all;

Grant succeeded.

SQL> conn c##usef/a@pdb18c

Connected.

SQL>  alter session set container=cdb$root;

ORA-01031: insufficient privileges

 

همانطور که ملاحضه شد، کاربر c##usef، دسترسی لازم را برای اجرای دستور set container ندارد و برای انجام این کار توسط کاربر c##usef، باید مجوز set container را به ان اهدا کرد:

 

SQL> conn sys as sysdba

SQL> grant set container to c##usef;

Grant succeeded.

SQL> conn c##usef/a@pdb18c

Connected.

SQL> alter session set container=cdb$root;

Session altered.

 

وضیعت common user بعد از unplug

در ادامه خواهید دید که وضیعت common userها بعد از unplug شدن یک pdb، به چه صورتی در خواهد امد(در cdb جدید). قبل از عملیات unplug، common userای را در cdb1 ایجاد می کنیم:

 

–cdb1

SQL> create user c##usef identified by a container=all;

User created.

SQL> grant dba to  c##usef container=all;

Grant succeeded.

SQL>  alter session set container=PDB18C;

Session altered.

SQL> create table c##usef.tbl as select name from v$datafile;

Table created.

 

با در نظر گرفتن این مسئله، pdb مورد نظر را unplug می کنیم:

 

–cdb1:

SQL> alter pluggable database PDB18C close immediate;

Pluggable database altered.

SQL> alter pluggable database pdb18c unplug into ‘/18c/unplug.xml’;

Pluggable database altered.

SQL> drop pluggable database pdb18c;

Pluggable database dropped.

 

بعد از انجام مراحل unplug، عملیات plug این pdb را در cdb2 مجددا انجام می دهیم:

 

–cdb2

SQL> create pluggable database pdb18c using ‘/18c/unplug.xml’ nocopy tempfile reuse;

Pluggable database created.

SQL> alter pluggable database PDB18C open;

Pluggable database altered.

 

بعد از انجام عملیات plug، خواهیم دید که کاربر c##usef در وضیعت lock قرار خواهد داشت البته امکان دسترسی به اطلاعات جداول موجود در این کاربر در محیط pdb18c، امکان پذیر خواهد بود:

 

QL> select con_id,username,common from cdb_users where username like ‘C##USEF%’;

    CON_ID USERNAME   COM

———- ———- —

         4 C##USEF    YES

SQL> conn C##USEF/a@pdb18c

ORA-28000: The account is locked.

SQL> alter user C##USEF account unlock;

ORA-65146: account cannot be unlocked in a PDB while it is locked in the root

SQL> select USERNAME,ACCOUNT_STATUS from dba_users where username like ‘C##USEF%’;

USERNAME   ACCOUNT_STATUS

———- ——————————–

C##USEF    LOCKED

SQL> alter session set container=PDB18C;

Session altered.

SQL> select count(*) from C##USEF.tbl;

  COUNT(*)

———-

         4

برای حل مشکل قفل بودن این کاربر، می توان مراحل زیر را طی نمود:

 

SQL> alter pluggable database PDB18C close;

Pluggable database altered.

SQL> create user c##usef identified by a;

User created.

SQL> grant dba to c##usef container=all;

Grant succeeded.

SQL> alter pluggable database PDB18C open;

Pluggable database altered.

SQL> conn C##USEF/a@pdb18c

Connected.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *