Jede Instanz für genau eine Datenbank (Instanz = Datenbank), Benutzer sind ein Schema (Schema = User), jeder Benutzer hat einen Default-Tablespace
Exemplarische Verzeichnis- und Namenskonventionen am Beispiel einer Linuxumgebung
Basisverzeichnis für Installationen
Verzeichnis für einzelne Installationen
Basisverzeichnis für Datenbanken
Verzeichnis für einzelne Datenbanken
mkdir /opt/oracle/admin/MYDB mkdir /opt/oracle/oradata/MYDB
cp /opt/oracle/product/<version>/<installation>/dbs/init.ora /opt/oracle/product/<version>/<installation>/dbs/initMYDB.ora
vi /opt/oracle/product/<version>/<installation>/dbs/initMYDB.ora
db_name=MYDB shared_pool_size = 123232153 undo_management=AUTO
export ORACLE_BASE=/opt/oracle/app/oracle export ORACLE_HOME=/opt/oracle/product/<version>/<installation>/ export ORACLE_SID=MYDB
sqlplus "/ as sysdba"
startup nomount pfile=/opt/oracle/product/<version>/<installation>/dbs/initMYDB.ora;
create database MYDB logfile group 1 ('/opt/oracle/oradata/MYDB/redo1.log') size 100M, group 2 ('/opt/oracle/oradata/MYDB/redo2.log') size 100M, group 3 ('/opt/oracle/oradata/MYDB/redo3.log') size 100M character set AL32UTF8 national character set utf8 datafile '/opt/oracle/oradata/MYDB/system.dbf' size 500M autoextend on next 10M maxsize unlimited extent management local sysaux datafile '/opt/oracle/oradata/MYDB/sysaux.dbf' size 500M autoextend on next 10M maxsize unlimited undo tablespace undotbs1 datafile '/opt/oracle/oradata/MYDB/undotbs1.dbf' size 4G default temporary tablespace temp tempfile '/opt/oracle/oradata/MYDB/temp01.dbf' size 100M;
shutdown startup
@?/rdbms/admin/catalog.sql
@?/rdbms/admin/catproc.sql
Größe 10M fest
CREATE TABLESPACE tsd_myuser DATAFILE '/opt/oracle/oradata/MYDB/tsd_myuser.dbf' SIZE 10M;
Größe 10M autoextend max 100M
CREATE TABLESPACE tsd_myuser DATAFILE '/opt/oracle/oradata/MYDB/tsd_myuser.dbf' SIZE 10M AUTOEXTEND ON NEXT 10M MAXSIZE 100M;
CREATE TABLESPACE tsd_myuser DATAFILE '/opt/oracle/oradata/MYDB/tsd_myuser.dbf' SIZE 100M AUTOEXTEND OFF LOGGING ONLINE PERMANENT EXTENT MANAGEMENT LOCAL UNIFORM SIZE 128K BLOCKSIZE 8K SEGMENT SPACE MANAGEMENT AUTO;
Datafile ändern
ALTER DATABASE DATAFILE '/opt/oracle/oradata/MYDB/tsd_myuser.dbf' resize 500M; ALTER DATABASE DATAFILE '/opt/oracle/oradata/MYDB/tsd_myuser.dbf' AUTOEXTEND ON NEXT 500M MAXSIZE 2G;
ALTER DATABASE TEMPFILE '/opt/oracle/oradata/MYDB/temp01.dbf' resize 500M; ALTER DATABASE TEMPFILE '/opt/oracle/oradata/MYDB/temp01.dbf' AUTOEXTEND ON NEXT 500M MAXSIZE 2G;
CREATE USER myuser IDENTIFIED BY kennwort DEFAULT TABLESPACE tsd_myuser TEMPORARY TABLESPACE temp PROFILE DEFAULT ACCOUNT UNLOCK; -- Roles GRANT DBA TO myuser; GRANT CONNECT TO myuser; ALTER USER myuser DEFAULT ROLE ALL; -- System Privilege GRANT UNLIMITED TABLESPACE TO myuser;
Unlock a password
ALTER USER username ACCOUNT UNLOCK;
Lock a password
ALTER USER username ACCOUNT LOCK;
Change password of an unlocked account
ALTER USER username IDENTIFIED BY password;
Change password of a locked account
ALTER USER username IDENTIFIED BY password ACCOUNT UNLOCK;
User | Password |
---|---|
sysdba | |
system | manager |
sys | change_on_install |
exp SYSTEM/<password> FULL=y FILE=dba.dmp LOG=dba.log CONSISTENT=y
exp <user>/<password> FIlE=scott.dmp OWNER=scott
exp SYSTEM/<password> FILE=expdat.dmp TABLES=(scott.emp,hr.countries)
exp <user>/<password> FILE=scott.dmp TABLES=(emp,dept)
imp SYSTEM/<password> FULL=y FIlE=dba.dmp
imp <user>/<password> FIlE=scott.dmp
imp SYSTEM/<password> FIlE=dba.dmp FROMUSER=scott TABLES=(dept,emp)
imp SYSTEM/<password> FROMUSER=blake TOUSER=scott FILE=blake.dmp TABLES=(unit,manager)
http://www.datenbank-start.de/zustaende.htm
Im Zustand NOMOUNT ist die Datenbank Instanz gestartet. D.h. die Prozesse (Windows: Threads) laufen und der Hauptspeicher (SGA) ist allokiert. Die Initialisierungsdatei ("initora") wurde gelesen, so dass diverse Informationen über die Datenbank bereits bekannt sind (z.B. wo sich die controlfiles) befinden.
Dieser Zustand wird normalerweise nicht manuell herbeigeführt. Lediglich für die Befehle create database, create controlfile, sowie für das Einschalten des Archivelog-Modus mit dem Befehl archive log start wird er benötigt.
In der Initialisierungsdatei sind die control files mit ihren Pfaden eingetragen. Mehrere Einträge bedeuten, dass die Dateien gespiegelt sind. Sie werden gelesen und abgeglichen. Sollten Differenzen zwischen den Dateien auftauchen erscheint eine Fehlermeldung und die Datenbank kann nicht gestartet werden. Der Administrator muss dass manuell durch kopieren dafür sorgen, dass alle Dateien identisch sind. Er sollte dazu die neueste Datei verwenden!
In den Control-Dateien sind Informationen über die eigentlichen Datenbankdateien abgelegt. Die Dateien sind aber noch nicht geöffnet, so dass in diesem Zustand einigen administrative Aufgaben durchgeführt werden.
Typisches Beispiel ist das Umbenennen bzw. verschieben von Dateien:
alter database rename file '<alter Dateiname inkl. Pfad>' to '<neuer Dateiname inkl. Pfad>';
Achtung! Es handelt sich nur um die Bekanntmachung eines neuen Namens. Deshalb ist vorher die Datei auf Betriebssystemebene umzubenennen bzw. zu kopieren.
startup
startup pfile=<init<SID>.ora-Datei inkl. Pfad> [ <Zustand> ]
startup force [ <Zustand> ]
startup restrict [ <Zustand> ]
alter system disable restricted session;
shutdown
shutdown transactional
shutdown immediate
shutdown abort
shutdown abort /* Datenbank ist in einem inkonsistenten Zustand */ startup /* Ein Datenbank Recovery wird automatisch durchgeführt */ shutdown /* Datenbank ist wieder konsistent */
1. zur Sicherheit, und 2. soll er selber wegräumen was er wegräumen kann...
Zeit geben zum aufräumen, gucken ob sich was tut in den folgenden Bereichen.
rm .../dbs/sgadef<sid>.dbf
ps -ef | grep ora_ | grep &ORACLE_SID
Als erstes den "...pmon..."-Prozess, dann etwas warten, die anderen folgen ihrem pmon vermutlich bald ins digitale Nirvana.
kill -9 <Process_ID_Number>
ipcs ipcrm -m <Shared_Memory_ID_Number> ipcrm -s <Semaphore_ID_Number>
rm .../dbs/lk<sid>
Instanz starten.
Ich persönlich versuche nach erfolgreichem Start noch ein mal shutdown und startup, um zu gucken ob sie sauber runter kommt.
show parameters
Parameter | Beschriebung |
---|---|
OPEN_CURSORS = int | Max # cursors per session |
PROCESSES = int | User processes |
SESSIONS = int | Max no. of user and system sessions |
create pfile from spfile;
create pfile=/path/to/backup.ora from spfile;
create spfile from pfile=/path/to/backup.ora
alter system set db_recovery_file_dest_size=10g;
Ohne Init-Datei schlägt der Start fehl.
ORACLE_HOME/dbs
ORACLE_HOME/database
init<SID>.ora
desc v$parameter
show parameter control_files;
select name, value from v$parameter where name = 'control_files';
Ein pfile mit dem folgenden Inhalt anlegen:
SPFILE=/path/to/spfiletestdb.ora
Überwachen der Alert Log File und Trace Files
Zur Fehlerüberwachung und Diagnostik dienen mehrere Arten von Log/Trace-Files. Diese ASCII-Dateien können mit den üblichen Unix-Befehlen (tail, grep, ...) betrachtet und ausgewertet werden.
Pfad wird in BACKGROUND_DUMP_DEST festgelegt. Dies ist die eigentliche Log-Datei für die Instanz. Diese sollte regelmäßig untersucht und auch mal gelegentlich geleert werden.
find . -type f -name alert*.log
Pfad wird in BACKGROUND_DUMP_DEST festgelegt. Die Benennung ist: sid_prozessname_pid.trc. Wobei der Prozessname sich aus dem Background-Prozess ergibt (LGWR, DBWR, ...). Die PID ist die PID vom Betriebssystem. Diese Dateien werden nur bei Fehlern angelegt. Diese sollte regelmäßig untersucht und dann gelöscht werden.
find . -type f -name *.trc
Pfad wird in USER_DUMP_DEST festgelegt. Die Bennenung ist: sid_ora_PID.trc. Diese Dateien werden nur bei Fehlern angelegt. Diese sollte regelmäßig untersucht und dann gelöscht werden.
find . -type f -name *.trc
alter session set SQL_TRACE = TRUE;
SQL_TRACE ist ein statischer Parameter.
Achtung: Es entstehen sehr viele Daten, da z.B. jedes SQL-Statement geloggt wird. Die Default-Einstellung ist TRUE und sollte daher auf FALSE gesetzt werden.
Mit einfachsten Mitteln auf der Console kann man zum Beispiel das tun:
while true; do sleep 5; clear; [z.B. diverse find's o.ä.]; done
Cursor
SELECT * FROM v$open_cursor;
Anzahl Cursor
SELECT count(*) FROM v$open_cursor;
Cursor je Session
SELECT SID, count(*) FROM v$open_cursor GROUP BY SID;
Cursor je User
SELECT USER_NAME, count(*) FROM v$open_cursor GROUP BY USER_NAME;
export ORACLE_SID=datenbankname
sqlplus "/ as sysdba"
SELECT * FROM cat;
SELECT * FROM dba_users
SELECT * FROM v$session
SPOOL liste.txt
set markup HTML on spool index.html select * from tab; spool off set markup HTML off
SELECT * FROM user_sys_privs;
SELECT * FROM dba_sys_privs;
SELECT * FROM session_privs;
SELECT * FROM dba_roles;
SELECT EXECUTIONS, USERS_EXECUTING, username, sql_text FROM v$session se, v$sql sq WHERE se.sql_address = sq.address;
COPY FROM scott/tiger@db1 TO scott/tiger@db2 INSERT mytable USING select * from mytable;
EXECUTE system.kill my sessions;
/* So kommentiert man mehrzeilig */ --So kommentiert man einzeilig
SET serveroutput ON; DECLARE -- Deklarationsblock variablenname datentyp; variablenname datentyp := wert; variablenname tabellenname.spaltenname%TYPE; CURSOR cursorname IS SELECT spalte FROM tabelle; exception_name EXCEPTION; PRAGMA exception_init(exception_name, -exception_number); BEGIN -- Ausführungsteil SELECT spalte INTO variable FROM tabelle WHERE ...; LOOP ... EXIT WHEN BEDINGUNG; END LOOP; WHILE Bedingung LOOP ... END LOOP; FOR i IN REVERSE 1 .. 5 LOOP DBMS_OUTPUT.put_line(TO_CHAR(i)); END LOOP; IF ... THEN ...; ELSIF ... THEN ...; ELSE ...; END IF; raise <exception_name>; EXCEPTION -- Ausnahmeverarbeitung WHEN exception_name THEN -- Execptionhandlung für die Exception exception_name ... WHEN OTHERS THEN -- Execptionhandlung für alle restlichen, nicht erwarteten Exceptions ... END;
Einen Wert bei jedem Zugriff Abfragen
SELECT spalte FROM tabelle WHERE spalte LIKE '&suchwert';
Einen Wert einmalig Abfragen, wird bei jedem Zugriff wieder verwendet
SELECT spalte FROM tabelle WHERE spalte LIKE '&&suchwert';
CREATE TABLE menschen ( mensch_id number(10) not null, mensch_name varchar2(50) not null, land_id number(10), CONSTRAINT pk_menschen PRIMARY KEY (mensch_id), CONSTRAINT fk_länder FOREIGN KEY (land_id) REFERENCES länder(land_id) );
Erzeugen aus anderer Tabelle
CREATE TABLE tabelle2 AS (SELECT * FROM tabelle2);
CREATE TABLE tabelle2 AS (SELECT * FROM tabelle2 WHERE tabelle2.id > 5000);
CREATE TABLE tabelle2 AS (SELECT spalte1, spalte2 FROM tabelle2 WHERE tabelle2.id > 5000);
Kopieren einer Tabelle ohne Zeilen zu übernehmen durch getrickst negative Bedingung
CREATE TABLE tabelle2 AS (SELECT * FROM tabelle1 WHERE 1=2);
ALTER TABLE tabelle1 RENAME TO tabelle2;
ALTER TABLE tabelle1 ADD spalte1 spaltendefinition;
ALTER TABLE tabelle1 MODIFY spalte1 spaltendefinition_neu;
ALTER TABLE tabelle1 RENAME COLUMN spalte1 TO spalte2;
ALTER TABLE tabelle1 DROP COLUMN spalte1;
DROP TABLE tabelle;
Insert into tabelle (spalte1, spalte2, spalte3, spalte4) Values ('wert1', 'wert2', 'wert3', 'wert4');
UPDATE table SET columnA = '' UPDATE table SET columnA = columnB
Temporäre Tabelle erstellen, Update durchführen, temporäre Tabelle wegwerfen
-- Daten zusammenführen CREATE TABLE temp_tabelle AS SELECT qt1.id AS "qt1_id", qt2.spalte1, qt2.spalte2 FROM quell_tabelle2 qt2, zuo_tabelle zuo, quell_tabelle1 qt1 WHERE qt2.id = zuo.id AND zuo.id = qt1.id; -- Update durchführen UPDATE quell_tabelle1 qt1 SET spalte2 = (SELECT DISTINCT spalte2 FROM temp_tabelle WHERE qt1.id = temp_tabelle.qt1_id ) WHERE EXISTS (SELECT spalte2 FROM temp_tabelle WHERE qt1.id = temp_tabelle.qt1_id ); UPDATE quell_tabelle1 qt1 SET spalte1 = (SELECT DISTINCT spalte1 FROM temp_tabelle WHERE qt1.id = temp_tabelle.qt1_id ) WHERE EXISTS (SELECT spalte1 FROM temp_tabelle WHERE qt1.id = temp_tabelle.qt1_id ); -- Testabfrage SELECT qt1.id AS "qt1_id", qt1.spalte1, qt1.spalte2, qt2.id, qt2.spalte1, qt2.spalte2 FROM quell_tabelle2 qt2, zuo_tabelle zuo, quell_tabelle1 qt1 WHERE qt2.id = zuo.id AND zuo.id = qt1.id; -- Aufräumen DROP TABLE temp_tabelle; -- Abschließen commit;
DELETE FROM tabelle WHERE name='wegdamit';
Lösche alles aus tabelle_a wenn es schon in tabelle_b ist
DELETE FROM tabelle_a WHERE EXISTS ( select tabelle_b.name from tabelle_b where tabelle_b.objekt_id = tabelle_a.objekt_id and tabelle_b.objekt_name = 'doppelagent' );
Lösche alles aus tabelle_a wenn feld1 und feld2 nicht feldx und feldy entspricht
DELETE FROM tabelle_a WHERE NOT EXISTS ( select * from tabelle_b where tabelle_a.field1 = tabelle_b.fieldx and tabelle_a.field2 = tabelle_b.fieldz );
UPDATE tabelle SET spalte1 = to_number(SUBSTR(to_char(spalte2), 1, 2) || '000000')
Kann als Bedingung für Subquerys verwendet werden, wenn das Subquery mindestens eine Zeile liefert. Ist allerdings sehr ineffizient, da das Subquery für jede Zeile der befragten Tabelle ausgeführt wird.
SELECT spalte FROM tabelle WHERE [NOT] EXISTS ( subquery );
Zwei Beispiele, ein mal alle Kunden die mindestens eine Bestellung haben, ein mal alle Kunden die keine Bestellung haben.
SELECT * FROM kunden WHERE EXISTS (select * from bestellungen where kunden.kunde_id = bestellungen.kunde_id); SELECT * FROM kunden WHERE NOT EXISTS (select * from bestellungen where kunden.kunde_id = bestellungen.kunde_id);
Copyright © 2024