Sichtbarkeit von Daten in Multitenant bestimmen
Mit der Multitenant-Architektur wurden auch neue Dictionary-Views eingeführt. Zu den vorhandenen Views mit den Präfixen USER_, ALL_ und DBA_ gesellten sich weitere Views mit dem Präfix CDB_. Die Inhalte dieser Views richten sich nach den Rechten des angemeldeten Benutzers und lässt sich grob so zusammenfassen:
- USER_: Alles, was dem angemeldeten Benutzer im aktuellen Container selbst gehört
- ALL_: Alles, worauf der angemeldete Benutzer im aktuellen Container Berechtigungen hat
- DBA_: Alles, was es im aktuellen Container gibt
- CDB_: Alles, was es in der gesamten CDB gibt
Natürlich gibt es auch V$-Views, die Containerdaten enthalten, also Daten aus PDBs und CDB$ROOT. Am Ende betrifft das eine ganze Menge Views:
SQL> SELECT count(*) FROM cdb_views WHERE container_data = 'Y';
COUNT(*)
----------
3118
Wie verhalten sich diese Views nun auf den verschiedenen Ebenen bzw. was sind deren Inhalte? Dazu wird zunächst ein Common User erstellt und mit den Privilegien ausgestattet um das Dictionary abfragen zu dürfen.
SQL> create user c##marco identified by "R0b0tr0N##";
User created.
SQL> grant dba, create session to c##marco container=all;
Grant succeeded.
Exemplarisch fragt man nun eine Dictionary-View ab um zu ermitteln, was der neu angelegte Benutzer sehen kann:
SQL> conn c##marco/********
Connected.
SQL> select con_id, name from v$datafile
2 order by 1;
CON_ID NAME
---------- --------------------------------------------------------------------------------------------------------------
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_undotbs1_kq6ld1qb_.dbf
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_sysaux_kq6lbyd0_.dbf
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_system_kq6l8vf4_.dbf
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_users_kq6ld4xm_.dbf
4 rows selected.
SQL> alter session set container=pdb1;
Session altered.
SQL> select con_id, name from v$datafile;
CON_ID NAME
---------- ------------------------------------------------------------------------------------------------------------------------
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_system_kq6nz8kh_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_sysaux_kq6nz8kt_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_undotbs1_kq6nz8kv_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_users_ksfwjspy_.dbf
Offenbar sieht man zunächst nur die Datendateien des CDB$ROOT-Containers, nicht aber die der einzelnen PDBs. Wechselt man in die PDB, sieht man entsprechend nur die Datendateien, die zu dieser PDB gehören. Das lässt sich aber beeinflussen. Man kann dem Benutzer erlauben, alle Daten in allen Containern zu sehen. Der Standard ist, nur die Daten im aktuellen Container sehen zu dürfen.
SQL> conn / as sysdba
Connected.
SQL> alter user c##marco set container_data=all container=current;
User altered.
SQL> SELECT username,
2 owner,
3 object_name,
4 all_containers,
5 container_name
6 FROM cdb_container_data
7 WHERE username = 'C##MARCO'
8 ORDER BY 1,2,3;
USERNAME OWNER OBJECT_NAME A CONTAINER_NAME
-------------------- -------------------- -------------------- - --------------------
C##MARCO Y
Nun darf der Common User auch die Daten der PDBs innerhalb der CDB sehen. Das gilt mit der Einstellung "CONTAINER_DATA=ALL" für alle vorhandenen PDBs sowie auch für alle zukünftigen PDBs.
SQL> select con_id, name from v$datafile
2 order by 1;
CON_ID NAME
---------- --------------------------------------------------------------------------------------------------------------
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_undotbs1_kq6ld1qb_.dbf
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_sysaux_kq6lbyd0_.dbf
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_system_kq6l8vf4_.dbf
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_users_kq6ld4xm_.dbf
2 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_system_kq6m8z4c_.dbf
2 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_sysaux_kq6m8z7g_.dbf
2 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_undotbs1_kq6m8zgv_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_undotbs1_kq6nz8kv_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_users_ksfwjspy_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_system_kq6nz8kh_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_sysaux_kq6nz8kt_.dbf
4 /u01/app/oracle/oradata/ORCL19/EF6055BDD31101A7E053A024100A1966/datafile/o1_mf_sysaux_ks5op8o9_.dbf
4 /u01/app/oracle/oradata/ORCL19/EF6055BDD31101A7E053A024100A1966/datafile/o1_mf_undotbs1_ks5op8o9_.dbf
4 /u01/app/oracle/oradata/ORCL19/EF6055BDD31101A7E053A024100A1966/datafile/o1_mf_system_ks5op8n8_.dbf
5 /u01/app/oracle/oradata/ORCL19/EF608A6519330511E053A024100A91E2/datafile/o1_mf_system_ks5pktn8_.dbf
5 /u01/app/oracle/oradata/ORCL19/EF608A6519330511E053A024100A91E2/datafile/o1_mf_sysaux_ks5pktn9_.dbf
5 /u01/app/oracle/oradata/ORCL19/EF608A6519330511E053A024100A91E2/datafile/o1_mf_undotbs1_ks5pktnb_.dbf
17 rows selected.
Nun sind also folgerichtig alle Datendateien in allen PDBs zu sehen. Da diese Einstellung sehr großzügig ist weil sie auch für noch anzulegende PDBs gilt, kann man die Einstellungen auch verfeinern und pro PDB einstellen, ob die Daten zu lesen sein dürfen oder eben nicht. Dazu wird zunächst die großzügige Einstellung entfernt.
SQL> alter user c##marco set container_data=default container=current;
User altered.
SQL> SELECT username,
2 owner,
3 object_name,
4 all_containers,
5 container_name
6 FROM cdb_container_data
7 WHERE username = 'C##MARCO'
8 ORDER BY 1,2,3;
no rows selected
Die Einstellungen werden nun feingranular pro PDB vergeben. Daten von PDBs, die später angelegt werden, sind daher nicht direkt sichtbar. Das muss dann wiederum je nach Bedarf nachgetragen werden.
SQL> alter user c##marco set container_data=(CDB$ROOT,PDB1) container=current;
User altered.
SQL> SELECT username,
2 owner,
3 object_name,
4 all_containers,
5 container_name
6 FROM cdb_container_data
7 WHERE username = 'C##MARCO'
8 ORDER BY 1,2,3;
USERNAME OWNER OBJECT_NAME A CONTAINER_NAME
-------------------- -------------------- -------------------- - --------------------
C##MARCO N PDB1
C##MARCO N CDB$ROOT
Man sieht, die Einstellung für "ALL_CONTAINERS" ist nun "No" und jeder Container, dessen Inhalte zu sehen sein dürfen, ist separat aufgelistet. Entsprechend sieht dann auch das Abfrageergebnis aus.
SQL> conn c##marco/********
Connected.
SQL> select con_id, name from v$datafile;
CON_ID NAME
---------- --------------------------------------------------------------------------------------------------------------
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_system_kq6l8vf4_.dbf
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_sysaux_kq6lbyd0_.dbf
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_undotbs1_kq6ld1qb_.dbf
1 /u01/app/oracle/oradata/ORCL19/datafile/o1_mf_users_kq6ld4xm_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_system_kq6nz8kh_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_sysaux_kq6nz8kt_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_undotbs1_kq6nz8kv_.dbf
3 /u01/app/oracle/oradata/ORCL19/ED7F830814134AADE053A024100A5D08/datafile/o1_mf_users_ksfwjspy_.dbf
8 rows selected.
Es sind nur Daten der CDB$ROOT und der PDB1 zu sehen, Daten aller anderen PDBs jedoch nicht. Auf diese Weise kann die Sichtbarkeit von Daten in verschiedenen Containern relativ fein geregelt werden. Gerade für Monitoring-User oder auch beim Einsatz von Application-PDBs kann das sehr nützlich sein.
Kommentare
Keine Kommentare