Init
This commit is contained in:
@@ -0,0 +1,420 @@
|
||||
# AGGREGATED_ALLOTMENT External Tables Setup
|
||||
|
||||
Ten dokument przedstawia kompletny przykład tworzenia trzech external tables dla tabeli `AGGREGATED_ALLOTMENT` według wzorca FILE PROCESSOR System.
|
||||
|
||||
## Przegląd tabeli źródłowej
|
||||
|
||||
**Tabela źródłowa:** `OU_TOP.AGGREGATED_ALLOTMENT`
|
||||
**Kolumna kluczowa do partycjonowania:** `ALLOTMENT_DATE` (DATE)
|
||||
**Liczba kolumn:** 43
|
||||
**Główne kolumny dat:** ALLOTMENT_DATE, VALUE_DATE, MATURITY_DATE
|
||||
|
||||
## Proces krok po kroku
|
||||
|
||||
### Krok 1: Tworzenie tabeli template (jeśli nie istnieje)
|
||||
|
||||
```sql
|
||||
-- Sprawdź czy template już istnieje
|
||||
SELECT table_name FROM all_tables
|
||||
WHERE owner = 'CT_ET_TEMPLATES' AND table_name = 'TOP_AGGREGATED_ALLOTMENT';
|
||||
|
||||
-- Jeśli nie istnieje, utwórz template table
|
||||
CREATE TABLE CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT
|
||||
AS SELECT * FROM OU_TOP.AGGREGATED_ALLOTMENT WHERE 1=2;
|
||||
|
||||
-- Weryfikacja struktury template
|
||||
SELECT column_name, data_type, data_length, nullable
|
||||
FROM user_tab_columns
|
||||
WHERE table_name = 'TOP_AGGREGATED_ALLOTMENT'
|
||||
ORDER BY column_id;
|
||||
```
|
||||
|
||||
**Cel:**
|
||||
- Template definiuje strukturę dla external tables
|
||||
- Używa `WHERE 1=2` aby skopiować tylko strukturę, bez danych
|
||||
- Znajduje się w schemacie `CT_ET_TEMPLATES` dla centralnego zarządzania
|
||||
|
||||
### Krok 2: Tworzenie trzech external tables
|
||||
|
||||
**Metoda zalecana:** Użyj pakietu `ODS.FILE_MANAGER_ODS` (działa z każdego kontekstu użytkownika)
|
||||
|
||||
```sql
|
||||
-- External table dla INBOX (pliki przychodzące)
|
||||
BEGIN
|
||||
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_INBOX',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'INBOX/TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvInboxBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
-- External table dla ODS (dane operacyjne)
|
||||
BEGIN
|
||||
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ODS',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'ODS/TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
-- External table dla ARCHIVE (dane historyczne)
|
||||
BEGIN
|
||||
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
```
|
||||
|
||||
**Metoda alternatywna:** Użyj pakietu `CT_MRDS.FILE_MANAGER` (wymaga kontekstu użytkownika ODS)
|
||||
|
||||
```sql
|
||||
-- UWAGA: Te komendy muszą być wykonane jako użytkownik ODS
|
||||
-- ze względu na AUTHID CURRENT_USER w pakiecie FILE_MANAGER
|
||||
|
||||
-- External table dla INBOX (pliki przychodzące)
|
||||
BEGIN
|
||||
CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_INBOX',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'INBOX/TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvInboxBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
-- External table dla ODS (dane operacyjne)
|
||||
BEGIN
|
||||
CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ODS',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'ODS/TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
-- External table dla ARCHIVE (dane historyczne)
|
||||
BEGIN
|
||||
CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
```
|
||||
|
||||
### Krok 3: Eksport istniejących danych
|
||||
|
||||
```sql
|
||||
-- Eksport wszystkich danych historycznych
|
||||
BEGIN
|
||||
CT_MRDS.FILE_MANAGER.EXPORT_TABLE_DATA_BY_DATE(
|
||||
pSchemaName => 'OU_TOP', -- Schema źródłowa
|
||||
pTableName => 'AGGREGATED_ALLOTMENT', -- Tabela źródłowa
|
||||
pKeyColumnName => 'ALLOTMENT_DATE', -- Kolumna do partycjonowania
|
||||
pBucketName => 'mrds_history_poc', -- Bucket docelowy
|
||||
pFolderName => 'TOP/AGGREGATED_ALLOTMENT' -- Folder docelowy
|
||||
-- pMinDate domyślnie DATE '1900-01-01' (eksportuje wszystkie dane historyczne)
|
||||
-- pMaxDate domyślnie SYSDATE (eksportuje dane do bieżącej daty)
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
-- Eksport danych z określonego zakresu dat
|
||||
BEGIN
|
||||
CT_MRDS.FILE_MANAGER.EXPORT_TABLE_DATA_BY_DATE(
|
||||
pSchemaName => 'OU_TOP',
|
||||
pTableName => 'AGGREGATED_ALLOTMENT',
|
||||
pKeyColumnName => 'ALLOTMENT_DATE',
|
||||
pBucketName => 'mrds_history_poc',
|
||||
pFolderName => 'TOP/AGGREGATED_ALLOTMENT',
|
||||
pMinDate => DATE '2024-01-01', -- Od 2024-01-01
|
||||
pMaxDate => DATE '2024-12-31' -- Do 2024-12-31
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
-- Eksport tylko najnowszych danych (ostatnie 90 dni)
|
||||
BEGIN
|
||||
CT_MRDS.FILE_MANAGER.EXPORT_TABLE_DATA_BY_DATE(
|
||||
pSchemaName => 'OU_TOP',
|
||||
pTableName => 'AGGREGATED_ALLOTMENT',
|
||||
pKeyColumnName => 'ALLOTMENT_DATE',
|
||||
pBucketName => 'mrds_history_poc',
|
||||
pFolderName => 'TOP/AGGREGATED_ALLOTMENT',
|
||||
pMinDate => SYSDATE - 90 -- Ostatnie 90 dni
|
||||
);
|
||||
END;
|
||||
/
|
||||
```
|
||||
|
||||
### Krok 4: Utworzenie kopii bezpieczeństwa (legacy table)
|
||||
|
||||
```sql
|
||||
-- Zmiana nazwy oryginalnej tabeli na legacy
|
||||
ALTER TABLE OU_TOP.AGGREGATED_ALLOTMENT
|
||||
RENAME TO AGGREGATED_ALLOTMENT_LEGACY;
|
||||
|
||||
-- Weryfikacja
|
||||
SELECT table_name FROM user_tables
|
||||
WHERE table_name LIKE '%AGGREGATED_ALLOTMENT%';
|
||||
```
|
||||
|
||||
### Krok 5: Utworzenie widoku kompatybilności
|
||||
|
||||
```sql
|
||||
-- Nadanie uprawnień do external table ODS
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ODS TO OU_TOP;
|
||||
|
||||
-- Utworzenie widoku z oryginalną nazwą tabeli
|
||||
CREATE OR REPLACE VIEW OU_TOP.AGGREGATED_ALLOTMENT AS
|
||||
SELECT * FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS;
|
||||
|
||||
-- Weryfikacja dostępu
|
||||
SELECT COUNT(*) FROM OU_TOP.AGGREGATED_ALLOTMENT;
|
||||
```
|
||||
|
||||
## Parametry procedur
|
||||
|
||||
### CREATE_EXTERNAL_TABLE
|
||||
|
||||
```sql
|
||||
PROCEDURE CREATE_EXTERNAL_TABLE (
|
||||
pTableName IN VARCHAR2, -- Nazwa external table do utworzenia
|
||||
pTemplateTableName IN VARCHAR2, -- Template table definiujący strukturę
|
||||
pPrefix IN VARCHAR2, -- Ścieżka w Oracle Cloud Storage
|
||||
pBucketUri IN VARCHAR2, -- URI bucket'a (domyślnie ENV_MANAGER.gvInboxBucketUri)
|
||||
pFileName IN VARCHAR2, -- Nazwa pliku (opcjonalne)
|
||||
pDelimiter IN VARCHAR2 -- Separator (domyślnie ',')
|
||||
);
|
||||
```
|
||||
|
||||
### EXPORT_TABLE_DATA_BY_DATE
|
||||
|
||||
```sql
|
||||
PROCEDURE EXPORT_TABLE_DATA_BY_DATE (
|
||||
pSchemaName IN VARCHAR2, -- Schema zawierający tabelę źródłową
|
||||
pTableName IN VARCHAR2, -- Nazwa tabeli do eksportu
|
||||
pKeyColumnName IN VARCHAR2, -- Kolumna do filtrowania dat
|
||||
pBucketName IN VARCHAR2, -- Nazwa bucket'a Oracle Cloud Storage
|
||||
pFolderName IN VARCHAR2, -- Ścieżka folderu w bucket'ie
|
||||
pMinDate IN DATE, -- Data minimalna (domyślnie DATE '1900-01-01')
|
||||
pMaxDate IN DATE, -- Data maksymalna (domyślnie SYSDATE)
|
||||
pNamespace IN VARCHAR2, -- OCI namespace (domyślnie ENV_MANAGER.gvNameSpace)
|
||||
pRegion IN VARCHAR2, -- OCI region (domyślnie ENV_MANAGER.gvRegion)
|
||||
pCredentialName IN VARCHAR2 -- OCI credentials (domyślnie ENV_MANAGER.gvCredentialName)
|
||||
);
|
||||
```
|
||||
|
||||
## Struktura przechowywania w chmurze
|
||||
|
||||
```
|
||||
Oracle Cloud Storage Bucket
|
||||
├── INBOX/
|
||||
│ └── TOP/
|
||||
│ └── AGGREGATED_ALLOTMENT/
|
||||
│ └── pliki_CSV_lub_PARQUET
|
||||
├── ODS/
|
||||
│ └── TOP/
|
||||
│ └── AGGREGATED_ALLOTMENT/
|
||||
│ └── pliki_CSV_lub_PARQUET
|
||||
└── TOP/
|
||||
└── AGGREGATED_ALLOTMENT/
|
||||
├── 2024_01/
|
||||
├── 2024_02/
|
||||
└── ...
|
||||
└── pliki_PARQUET_partycjonowane_miesięcznie
|
||||
```
|
||||
|
||||
## Weryfikacja i testowanie
|
||||
|
||||
### Sprawdzenie utworzonych external tables
|
||||
|
||||
```sql
|
||||
-- Lista utworzonych external tables
|
||||
SELECT table_name, table_type
|
||||
FROM user_tables
|
||||
WHERE table_name LIKE '%AGGREGATED_ALLOTMENT%'
|
||||
ORDER BY table_name;
|
||||
|
||||
-- Sprawdzenie external locations
|
||||
SELECT table_name, location
|
||||
FROM user_external_locations
|
||||
WHERE table_name LIKE '%AGGREGATED_ALLOTMENT%'
|
||||
ORDER BY table_name;
|
||||
```
|
||||
|
||||
### Test dostępu do danych
|
||||
|
||||
```sql
|
||||
-- Test external table INBOX (może być pusta)
|
||||
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_INBOX;
|
||||
|
||||
-- Test external table ODS (może być pusta do czasu załadowania danych)
|
||||
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS;
|
||||
|
||||
-- Test external table ARCHIVE (powinna zawierać wyeksportowane dane)
|
||||
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE;
|
||||
|
||||
-- Test widoku kompatybilności
|
||||
SELECT COUNT(*) FROM OU_TOP.AGGREGATED_ALLOTMENT;
|
||||
```
|
||||
|
||||
### Sprawdzenie wyeksportowanych plików
|
||||
|
||||
```sql
|
||||
-- Lista plików w bucket'ie archive
|
||||
SELECT object_name, size_in_bytes, time_created
|
||||
FROM DBMS_CLOUD.LIST_OBJECTS(
|
||||
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||
location_uri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri,
|
||||
prefix => 'TOP/AGGREGATED_ALLOTMENT'
|
||||
)
|
||||
ORDER BY time_created DESC;
|
||||
```
|
||||
|
||||
## Konwencje nazewnictwa
|
||||
|
||||
- **Template tables:** `CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT`
|
||||
- **External tables:**
|
||||
- `TOP_AGGREGATED_ALLOTMENT_INBOX` (pliki przychodzące)
|
||||
- `TOP_AGGREGATED_ALLOTMENT_ODS` (dane operacyjne)
|
||||
- `TOP_AGGREGATED_ALLOTMENT_ARCHIVE` (dane historyczne)
|
||||
- **Legacy table:** `AGGREGATED_ALLOTMENT_LEGACY`
|
||||
- **Widok kompatybilności:** `AGGREGATED_ALLOTMENT` (oryginalna nazwa)
|
||||
|
||||
## Rozwiązywanie problemów
|
||||
|
||||
### Problem: External table nie może znaleźć plików (ORA-29913)
|
||||
|
||||
```sql
|
||||
-- Sprawdź lokalizację external table
|
||||
SELECT table_name, location
|
||||
FROM user_external_locations
|
||||
WHERE table_name = 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE';
|
||||
|
||||
-- Sprawdź czy pliki istnieją w bucket'ie
|
||||
SELECT object_name
|
||||
FROM DBMS_CLOUD.LIST_OBJECTS(
|
||||
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||
location_uri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri,
|
||||
prefix => 'TOP/AGGREGATED_ALLOTMENT'
|
||||
);
|
||||
```
|
||||
|
||||
### Problem: Brak uprawnień
|
||||
|
||||
```sql
|
||||
-- Nadaj uprawnienia SELECT na external tables
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_INBOX TO OU_TOP;
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ODS TO OU_TOP;
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE TO OU_TOP;
|
||||
|
||||
-- Sprawdź uprawnienia
|
||||
SELECT grantee, privilege, table_name
|
||||
FROM user_tab_privs
|
||||
WHERE table_name LIKE '%AGGREGATED_ALLOTMENT%';
|
||||
```
|
||||
|
||||
## Kompletny skrypt setup
|
||||
|
||||
```sql
|
||||
-- ============================================================================
|
||||
-- AGGREGATED_ALLOTMENT External Tables Setup - Kompletny skrypt
|
||||
-- ============================================================================
|
||||
|
||||
-- Krok 1: Sprawdź i utwórz template table
|
||||
SELECT 'Sprawdzanie template table...' AS status FROM dual;
|
||||
|
||||
SELECT table_name FROM all_tables
|
||||
WHERE owner = 'CT_ET_TEMPLATES' AND table_name = 'TOP_AGGREGATED_ALLOTMENT';
|
||||
|
||||
-- Jeśli template nie istnieje, utwórz go:
|
||||
-- CREATE TABLE CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT
|
||||
-- AS SELECT * FROM OU_TOP.AGGREGATED_ALLOTMENT WHERE 1=2;
|
||||
|
||||
-- Krok 2: Tworzenie external tables (METODA ZALECANA)
|
||||
SELECT 'Tworzenie external tables...' AS status FROM dual;
|
||||
|
||||
BEGIN
|
||||
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_INBOX',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'INBOX/TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvInboxBucketUri
|
||||
);
|
||||
DBMS_OUTPUT.PUT_LINE('✓ Created INBOX external table');
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ODS',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'ODS/TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri
|
||||
);
|
||||
DBMS_OUTPUT.PUT_LINE('✓ Created ODS external table');
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
||||
);
|
||||
DBMS_OUTPUT.PUT_LINE('✓ Created ARCHIVE external table');
|
||||
END;
|
||||
/
|
||||
|
||||
-- Krok 3: Eksport istniejących danych
|
||||
SELECT 'Eksportowanie danych...' AS status FROM dual;
|
||||
|
||||
BEGIN
|
||||
CT_MRDS.FILE_MANAGER.EXPORT_TABLE_DATA_BY_DATE(
|
||||
pSchemaName => 'OU_TOP',
|
||||
pTableName => 'AGGREGATED_ALLOTMENT',
|
||||
pKeyColumnName => 'ALLOTMENT_DATE',
|
||||
pBucketName => 'mrds_history_poc',
|
||||
pFolderName => 'TOP/AGGREGATED_ALLOTMENT'
|
||||
);
|
||||
DBMS_OUTPUT.PUT_LINE('✓ Export completed');
|
||||
END;
|
||||
/
|
||||
|
||||
-- Krok 4: Backup oryginalnej tabeli
|
||||
SELECT 'Tworzenie kopii bezpieczeństwa...' AS status FROM dual;
|
||||
-- ALTER TABLE OU_TOP.AGGREGATED_ALLOTMENT RENAME TO AGGREGATED_ALLOTMENT_LEGACY;
|
||||
|
||||
-- Krok 5: Utworzenie widoku kompatybilności
|
||||
SELECT 'Tworzenie widoku kompatybilności...' AS status FROM dual;
|
||||
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ODS TO OU_TOP;
|
||||
|
||||
-- CREATE OR REPLACE VIEW OU_TOP.AGGREGATED_ALLOTMENT AS
|
||||
-- SELECT * FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS;
|
||||
|
||||
-- Weryfikacja
|
||||
SELECT 'Weryfikacja setup...' AS status FROM dual;
|
||||
|
||||
SELECT table_name, table_type
|
||||
FROM user_tables
|
||||
WHERE table_name LIKE '%AGGREGATED_ALLOTMENT%'
|
||||
ORDER BY table_name;
|
||||
|
||||
SELECT 'Setup zakończony pomyślnie!' AS status FROM dual;
|
||||
```
|
||||
|
||||
Ten kompletny przykład pokazuje wszystkie kroki potrzebne do migracji tabeli `AGGREGATED_ALLOTMENT` do systemu FILE PROCESSOR z trzema external tables dla różnych typów przechowywania danych.
|
||||
221
confluence/additions/AGGREGATED_ALLOTMENT_Problem_Resolution.md
Normal file
221
confluence/additions/AGGREGATED_ALLOTMENT_Problem_Resolution.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# AGGREGATED_ALLOTMENT External Tables - Rozwiązanie problemów
|
||||
|
||||
## 🔍 Diagnoza problemów
|
||||
|
||||
### Problem który napotkałeś:
|
||||
```sql
|
||||
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS;
|
||||
-- ORA-29913: error while processing ODCIEXTTABLEOPEN routine
|
||||
-- ORA-20401: Authorization failed
|
||||
```
|
||||
|
||||
### Przyczyny problemów:
|
||||
|
||||
#### 1. **Brak uprawnień do external tables**
|
||||
- External tables zostały utworzone w schemacie **ODS**
|
||||
- Próbujesz dostępu z schematu **CT_MRDS**
|
||||
- Brak uprawnień SELECT na ODS.TOP_AGGREGATED_ALLOTMENT_*
|
||||
|
||||
#### 2. **Niepoprawna konfiguracja ARCHIVE table**
|
||||
- **Użyty prefix:** `ARCHIVE/TOP/AGGREGATED_ALLOTMENT`
|
||||
- **Faktyczne pliki:** `TOP/AGGREGATED_ALLOTMENT/YEAR=2025/MONTH=08/*.parquet`
|
||||
- **Problem:** PARQUET files z Hive partitioning wymagają specjalnej konfiguracji
|
||||
|
||||
#### 3. **Weryfikacja plików** ✅
|
||||
```bash
|
||||
# ODS bucket - pliki CSV istnieją
|
||||
oci os object list --bucket-name data --prefix "ODS/TOP/AGGREGATED_ALLOTMENT/"
|
||||
# ✅ 14 plików CSV
|
||||
|
||||
# ARCHIVE bucket - pliki PARQUET z partycjonowaniem Hive
|
||||
oci os object list --bucket-name history --prefix "ARCHIVE/TOP/AGGREGATED_ALLOTMENT/"
|
||||
# ❌ Brak plików w tej lokalizacji
|
||||
|
||||
oci os object list --bucket-name history --prefix "TOP/AGGREGATED_ALLOTMENT/"
|
||||
# ✅ 8 plików PARQUET w strukturze YEAR=2025/MONTH=08/
|
||||
```
|
||||
|
||||
## 🔧 Rozwiązania
|
||||
|
||||
### Rozwiązanie 1: Nadanie uprawnień
|
||||
|
||||
```sql
|
||||
-- Jako ODS user lub ADMIN
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ODS TO CT_MRDS;
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_INBOX TO CT_MRDS;
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE TO CT_MRDS;
|
||||
|
||||
-- Test z CT_MRDS
|
||||
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS;
|
||||
```
|
||||
|
||||
### Rozwiązanie 2: Poprawa konfiguracji ARCHIVE table
|
||||
|
||||
```sql
|
||||
-- Jako ODS user
|
||||
DROP TABLE TOP_AGGREGATED_ALLOTMENT_ARCHIVE;
|
||||
|
||||
-- Poprawne utworzenie z właściwym prefixem
|
||||
BEGIN
|
||||
FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'TOP/AGGREGATED_ALLOTMENT', -- Bez "ARCHIVE/" prefix
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
```
|
||||
|
||||
### Rozwiązanie 3: Alternatywne podejście - tworzenie w CT_MRDS
|
||||
|
||||
```sql
|
||||
-- Jako CT_MRDS user - utwórz external tables w swoim schemacie
|
||||
BEGIN
|
||||
CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ODS_CT',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'ODS/TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE_CT',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
```
|
||||
|
||||
## 🧪 Testowanie rozwiązań
|
||||
|
||||
### Test 1: Weryfikacja external locations
|
||||
```sql
|
||||
SELECT table_name, location
|
||||
FROM all_external_locations
|
||||
WHERE table_name LIKE '%TOP_AGGREGATED_ALLOTMENT%'
|
||||
AND owner IN ('ODS', 'CT_MRDS')
|
||||
ORDER BY owner, table_name;
|
||||
```
|
||||
|
||||
### Test 2: Próba dostępu do danych
|
||||
```sql
|
||||
-- Test ODS (pliki CSV)
|
||||
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS;
|
||||
|
||||
-- Test pierwszych 5 rekordów
|
||||
SELECT * FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS WHERE ROWNUM <= 5;
|
||||
```
|
||||
|
||||
### Test 3: Weryfikacja ARCHIVE (pliki PARQUET)
|
||||
```sql
|
||||
-- Test ARCHIVE (pliki PARQUET z partycjonowaniem)
|
||||
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE;
|
||||
|
||||
-- Sprawdzenie partycji
|
||||
SELECT DISTINCT year, month
|
||||
FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE
|
||||
ORDER BY year, month;
|
||||
```
|
||||
|
||||
## 📊 Struktura plików w buckets
|
||||
|
||||
### Data bucket (ODS) - format CSV
|
||||
```
|
||||
data/
|
||||
└── ODS/
|
||||
└── TOP/
|
||||
└── AGGREGATED_ALLOTMENT/
|
||||
├── AGGREGATED_ALLOTMENT_202508_1_*.csv
|
||||
├── AGGREGATED_ALLOTMENT_202508_2_*.csv
|
||||
├── AGGREGATED_ALLOTMENT_202509_1_*.csv
|
||||
└── ... (14 plików CSV)
|
||||
```
|
||||
|
||||
### History bucket (ARCHIVE) - format PARQUET z partycjonowaniem Hive
|
||||
```
|
||||
history/
|
||||
└── TOP/
|
||||
└── AGGREGATED_ALLOTMENT/
|
||||
└── YEAR=2025/
|
||||
├── MONTH=08/
|
||||
│ ├── 202508_1_*.parquet
|
||||
│ ├── 202508_2_*.parquet
|
||||
│ ├── 202508_3_*.parquet
|
||||
│ └── 202508_4_*.parquet
|
||||
└── MONTH=09/
|
||||
├── 202509_1_*.parquet
|
||||
├── 202509_2_*.parquet
|
||||
├── 202509_3_*.parquet
|
||||
└── 202509_4_*.parquet
|
||||
```
|
||||
|
||||
## ⚠️ Uwagi dotyczące FILE_MANAGER
|
||||
|
||||
### Automatyczna detekcja formatu
|
||||
Pakiet `FILE_MANAGER.CREATE_EXTERNAL_TABLE` automatycznie wykrywa format na podstawie `pBucketUri`:
|
||||
|
||||
- **Jeśli** `pBucketUri` zawiera `gvArchiveBucketUri` → format PARQUET z partycjonowaniem Hive
|
||||
- **Jeśli** `pBucketUri` zawiera `gvDataBucketUri` lub `gvInboxBucketUri` → format CSV
|
||||
|
||||
### Konfiguracja środowiska
|
||||
```sql
|
||||
-- Sprawdzenie konfiguracji ENV_MANAGER
|
||||
SET SERVEROUTPUT ON;
|
||||
DECLARE
|
||||
v_inbox VARCHAR2(4000);
|
||||
v_data VARCHAR2(4000);
|
||||
v_history VARCHAR2(4000);
|
||||
BEGIN
|
||||
v_inbox := CT_MRDS.ENV_MANAGER.gvInboxBucketUri;
|
||||
v_data := CT_MRDS.ENV_MANAGER.gvDataBucketUri;
|
||||
v_history := CT_MRDS.ENV_MANAGER.gvArchiveBucketUri;
|
||||
DBMS_OUTPUT.PUT_LINE('Inbox: ' || v_inbox);
|
||||
DBMS_OUTPUT.PUT_LINE('Data: ' || v_data);
|
||||
DBMS_OUTPUT.PUT_LINE('History: ' || v_history);
|
||||
END;
|
||||
/
|
||||
```
|
||||
|
||||
## 🎯 Zalecane działania
|
||||
|
||||
### Krok 1: Nadaj uprawnienia (NAJSZYBSZE)
|
||||
```sql
|
||||
-- Jako ADMIN lub z uprawnieniami GRANT
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ODS TO CT_MRDS;
|
||||
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_INBOX TO CT_MRDS;
|
||||
```
|
||||
|
||||
### Krok 2: Przebuduj ARCHIVE table
|
||||
```sql
|
||||
-- Jako ODS user
|
||||
DROP TABLE TOP_AGGREGATED_ALLOTMENT_ARCHIVE;
|
||||
|
||||
BEGIN
|
||||
FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
||||
pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE',
|
||||
pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
|
||||
pPrefix => 'TOP/AGGREGATED_ALLOTMENT',
|
||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
-- Nadaj uprawnienia
|
||||
GRANT SELECT ON TOP_AGGREGATED_ALLOTMENT_ARCHIVE TO CT_MRDS;
|
||||
```
|
||||
|
||||
### Krok 3: Test końcowy
|
||||
```sql
|
||||
-- Z schematu CT_MRDS
|
||||
SELECT 'ODS' as source, COUNT(*) as row_count FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS
|
||||
UNION ALL
|
||||
SELECT 'ARCHIVE' as source, COUNT(*) as row_count FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE;
|
||||
```
|
||||
|
||||
Teraz external tables powinny działać poprawnie! 🎉
|
||||
173
confluence/additions/Oracle_External_Tables_Tolerance_Guide.md
Normal file
173
confluence/additions/Oracle_External_Tables_Tolerance_Guide.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# Oracle External Tables Tolerance Guide
|
||||
|
||||
## Podsumowanie Mechanizmów Tolerancji
|
||||
|
||||
Oracle External Tables mają zaskakująco wysoką tolerancję na różnice w strukturze plików CSV w porównaniu do definicji tabeli. To może prowadzić do nieoczekiwanych zachowań w systemach enterprise.
|
||||
|
||||
## 🎯 Kluczowe Mechanizmy
|
||||
|
||||
### 1. **Mapowanie Kolumn Po Nazwach (Nie Po Pozycji)**
|
||||
```csv
|
||||
-- Tabela: ID, NAME, STATUS
|
||||
-- CSV 1: ID,NAME,STATUS ✅ Standardowa kolejność
|
||||
-- CSV 2: STATUS,NAME,ID ✅ Inna kolejność - działa!
|
||||
-- CSV 3: NAME,ID,STATUS ✅ Również działa!
|
||||
```
|
||||
|
||||
**Wniosek**: Oracle mapuje po nagłówkach, nie po kolejności kolumn.
|
||||
|
||||
### 2. **Brakujące Kolumny = NULL**
|
||||
```csv
|
||||
-- Tabela: ID, NAME, STATUS, AMOUNT
|
||||
-- CSV: ID,NAME ⚠️ STATUS i AMOUNT = NULL!
|
||||
```
|
||||
|
||||
**Niebezpieczeństwo**: Plik z niepełną strukturą zostanie załadowany z NULL-ami.
|
||||
|
||||
### 3. **Dodatkowe Kolumny Są Ignorowane**
|
||||
```csv
|
||||
-- Tabela: ID, NAME, STATUS
|
||||
-- CSV: ID,NAME,STATUS,EXTRA1,EXTRA2,BONUS ✅ Nadmiarowe kolumny ignorowane
|
||||
```
|
||||
|
||||
**Wniosek**: Oracle nie protestuje przeciw dodatkowym danym.
|
||||
|
||||
### 4. **Walidacja Typów Danych Jest Egzekwowana**
|
||||
```csv
|
||||
-- Tabela: ID(NUMBER), NAME(VARCHAR2), CREATED_DATE(DATE)
|
||||
-- CSV: "ABC","John","not-a-date" ❌ Błędy konwersji typów = FAILURE
|
||||
```
|
||||
|
||||
**Wniosek**: Tutaj Oracle jest rygorystyczny!
|
||||
|
||||
## 📋 Praktyczne Przykłady
|
||||
|
||||
### Plik Demonstracyjny 1: Idealna Zgodność
|
||||
**demo_perfect_match.csv**
|
||||
```csv
|
||||
ID,NAME,DESCRIPTION,CREATED_DATE,STATUS,AMOUNT
|
||||
1,"Product A","Description A","2024-01-15","ACTIVE",100.50
|
||||
2,"Product B","Description B","2024-01-16","INACTIVE",200.75
|
||||
```
|
||||
**Rezultat**: ✅ 100% sukces
|
||||
|
||||
### Plik Demonstracyjny 2: Brakujące Kolumny
|
||||
**demo_missing_columns.csv**
|
||||
```csv
|
||||
ID,WRONG_COLUMN,INVALID_STRUCTURE
|
||||
1,"Some Data","More Data"
|
||||
2,"Other Data","Different Data"
|
||||
```
|
||||
**Rezultat**: ⚠️ Akceptowany z NULL-ami w brakujących kolumnach!
|
||||
|
||||
### Plik Demonstracyjny 3: Dodatkowe Kolumny
|
||||
**demo_extra_columns.csv**
|
||||
```csv
|
||||
ID,NAME,DESCRIPTION,CREATED_DATE,STATUS,AMOUNT,EXTRA1,EXTRA2,BONUS_FIELD
|
||||
1,"Product A","Description A","2024-01-15","ACTIVE",100.50,"Extra","More","Bonus"
|
||||
```
|
||||
**Rezultat**: ✅ Sukces - dodatkowe kolumny ignorowane
|
||||
|
||||
### Plik Demonstracyjny 4: Inna Kolejność
|
||||
**demo_different_order.csv**
|
||||
```csv
|
||||
STATUS,AMOUNT,ID,NAME,DESCRIPTION,CREATED_DATE
|
||||
"ACTIVE",100.50,1,"Product A","Description A","2024-01-15"
|
||||
```
|
||||
**Rezultat**: ✅ Sukces - mapowanie po nazwach
|
||||
|
||||
### Plik Demonstracyjny 5: Błędne Typy Danych
|
||||
**demo_data_type_errors.csv**
|
||||
```csv
|
||||
ID,NAME,DESCRIPTION,CREATED_DATE,STATUS,AMOUNT
|
||||
"NOT_NUMBER","Product A","Description A","INVALID_DATE","ACTIVE","NOT_AMOUNT"
|
||||
```
|
||||
**Rezultat**: ❌ Failure - błędy konwersji typów
|
||||
|
||||
## 🛡️ Implikacje Bezpieczeństwa i Biznesowe
|
||||
|
||||
### Problemy
|
||||
1. **Niekompletne dane akceptowane jako poprawne**
|
||||
2. **Brak walidacji reguł biznesowych**
|
||||
3. **Ciche pomijanie dodatkowych informacji**
|
||||
4. **Nieoczekiwane NULL-e w krytycznych polach**
|
||||
|
||||
### Rozwiązania
|
||||
1. **Walidacja na poziomie aplikacji** - nie polegaj tylko na External Tables
|
||||
2. **NOT NULL constraints** na krytycznych polach
|
||||
3. **Niestandardowa procedura VALIDATE_SOURCE_FILE_RECEIVED**
|
||||
4. **Dokładne monitorowanie statusów plików**
|
||||
|
||||
## 🔧 Implementacja w Naszym Systemie
|
||||
|
||||
### Dlaczego Naprawa VALIDATION_FAILED Była Krytyczna
|
||||
|
||||
Bez poprawnej obsługi wyjątków w `VALIDATE_SOURCE_FILE_RECEIVED`:
|
||||
- Pliki z niepełną strukturą przechodziły jako "READY_FOR_INGESTION"
|
||||
- Brak śledzenia problemów walidacji
|
||||
- Nieszczęsne dane w systemie produkcyjnym
|
||||
|
||||
### Nasza Naprawa
|
||||
```sql
|
||||
-- PRZED: Nieprawidłowe propagowanie wyjątków
|
||||
WHEN OTHERS THEN
|
||||
RAISE; -- ❌ Błędne!
|
||||
|
||||
-- PO: Prawidłowe zachowanie
|
||||
WHEN OTHERS THEN
|
||||
COMMIT; -- Zapisz status VALIDATION_FAILED
|
||||
RAISE ENV_MANAGER.ERR_FILE_VALIDATION_FAILED; -- ✅ Poprawne!
|
||||
```
|
||||
|
||||
### Rozszerzona Walidacja Constraint
|
||||
```sql
|
||||
-- Dodano 'VALIDATION_FAILED' do dozwolonych statusów
|
||||
PROCESSING_STATUS IN ('RECEIVED', 'VALIDATED', 'READY_FOR_INGESTION',
|
||||
'INGESTED', 'ARCHIVED', 'VALIDATION_FAILED')
|
||||
```
|
||||
|
||||
## 📊 Testowanie
|
||||
|
||||
### Pełny Test Demonstracyjny
|
||||
Uruchom: `test_EXTERNAL_TABLE_COMPLETE_DEMO.sql`
|
||||
|
||||
Ten test pokazuje:
|
||||
- 6 różnych scenariuszy tolerancji
|
||||
- Dokładne rezultaty każdego przypadku
|
||||
- Praktyczne wnioski dla systemu enterprise
|
||||
|
||||
### Oczekiwane Rezultaty
|
||||
```
|
||||
✅ Perfect Match → READY_FOR_INGESTION
|
||||
⚠️ Missing Columns → READY_FOR_INGESTION (z NULL-ami!)
|
||||
✅ Extra Columns → READY_FOR_INGESTION
|
||||
✅ Different Order → READY_FOR_INGESTION
|
||||
⚠️ Completely Wrong → READY_FOR_INGESTION (wszystko NULL!)
|
||||
❌ Data Type Errors → VALIDATION_FAILED
|
||||
```
|
||||
|
||||
## 💡 Najważniejsze Wnioski
|
||||
|
||||
1. **Oracle External Tables nie są "strict" w kwestii struktury**
|
||||
2. **Walidacja typów danych działa, walidacja biznesowa - nie**
|
||||
3. **Konieczne są dodatkowe mechanizmy kontroli jakości**
|
||||
4. **Monitoring statusów plików jest absolutnie krytyczny**
|
||||
5. **Nasze problemy z VALIDATION_FAILED były objawem szerszego problemu tolerancji**
|
||||
|
||||
## 🚨 Zalecenia Produkcyjne
|
||||
|
||||
### Obowiązkowe
|
||||
- [ ] Zawsze implementuj walidację biznesową w aplikacji
|
||||
- [ ] Monitoruj wszystkie statusy plików
|
||||
- [ ] Testuj z różnymi strukturami plików CSV
|
||||
- [ ] Dokumentuj wszystkie dozwolone formaty
|
||||
|
||||
### Opcjonalne ale Zalecane
|
||||
- [ ] Dodaj CHECK constraints dla kluczowych pól
|
||||
- [ ] Implementuj pre-processing walidację nagłówków
|
||||
- [ ] Stwórz katalog akceptowalnych struktur plików
|
||||
- [ ] Dodaj alerty na nieoczekiwane NULL-e
|
||||
|
||||
---
|
||||
|
||||
*Ten dokument powstał w wyniku odkrycia i naprawy krytycznego błędu w procedurze `PROCESS_SOURCE_FILE` oraz dogłębnego zbadania mechanizmów tolerancji Oracle External Tables.*
|
||||
256
confluence/additions/Resource_Principal_Configuration_Guide.md
Normal file
256
confluence/additions/Resource_Principal_Configuration_Guide.md
Normal file
@@ -0,0 +1,256 @@
|
||||
# Konfiguracja Resour```
|
||||
Name: database-resource-principal-dg
|
||||
Description: Dynamic group for database instances using Resource Principal
|
||||
|
||||
Matching Rules:
|
||||
ANY {instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaar57tzot3jyasvp7fayc2bpepcugg4prujw6ctql42nruxjh5w72a'}
|
||||
|
||||
# Alternatywnie, dla konkretnej instancji:
|
||||
ANY {instance.id = 'ocid1.instance.oc1..aaaaaaaa...'}
|
||||
|
||||
# Lub dla wszystkich instancji w tenancy:
|
||||
ANY {instance.compartment.id = 'ocid1.tenancy.oc1..aaaaaaaa4chmgn5j6rsdsrvghtasdhmjok67jdathiiusv6kdzmokzp6ajua'}
|
||||
```dla Oracle Cloud Database
|
||||
|
||||
## Przegląd
|
||||
|
||||
Resource Principal to mechanizm uwierzytelniania w Oracle Cloud Infrastructure (OCI), który pozwala instancjom compute (w tym Oracle Database) na bezpieczny dostęp do usług OCI bez konieczności przechowywania kluczy API lub haseł.
|
||||
|
||||
## 1. Wymagania wstępne
|
||||
|
||||
- Oracle Cloud Database działająca na OCI
|
||||
- Uprawnienia administratora w OCI Console
|
||||
- Dostęp do bazy danych jako ADMIN lub użytkownik z uprawnieniami DBMS_CLOUD
|
||||
|
||||
## 2. Konfiguracja w OCI Console
|
||||
|
||||
### 2.1 Utworzenie Dynamic Group
|
||||
|
||||
1. Zaloguj się do **OCI Console**
|
||||
2. Przejdź do **Identity & Security** → **Dynamic Groups**
|
||||
3. Kliknij **Create Dynamic Group**
|
||||
4. Wypełnij formularz:
|
||||
|
||||
```
|
||||
Name: database-resource-principal-dg
|
||||
Description: Dynamic group for database instances using Resource Principal
|
||||
|
||||
Matching Rules:
|
||||
ANY {instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaa...'}
|
||||
|
||||
# Alternatywnie, dla konkretnej instancji:
|
||||
ANY {instance.id = 'ocid1.instance.oc1..aaaaaaaa...'}
|
||||
|
||||
# Lub dla wszystkich instancji w tenancy:
|
||||
ANY {instance.compartment.id = tenancy.id}
|
||||
```
|
||||
|
||||
5. Kliknij **Create**
|
||||
|
||||
### 2.2 Znajdowanie OCID kompartmentu lub instancji
|
||||
|
||||
**Dla kompartmentu:**
|
||||
- Identity & Security → Compartments → [Wybierz kompartment] → OCID
|
||||
|
||||
**Dla instancji database:**
|
||||
- Oracle Database → [Wybierz bazę] → DB Connection → OCID
|
||||
|
||||
### 2.3 Utworzenie IAM Policy
|
||||
|
||||
1. Przejdź do **Identity & Security** → **Policies**
|
||||
2. Kliknij **Create Policy**
|
||||
3. Wypełnij formularz:
|
||||
|
||||
```
|
||||
Name: database-resource-principal-policy
|
||||
Description: Policy allowing database instances to access Object Storage
|
||||
|
||||
Policy Statements:
|
||||
Allow dynamic-group database-resource-principal-dg to manage objects in compartment ManagedCompartmentForPaaS
|
||||
Allow dynamic-group database-resource-principal-dg to manage buckets in compartment ManagedCompartmentForPaaS
|
||||
Allow dynamic-group database-resource-principal-dg to read objectstorage-namespaces in tenancy
|
||||
Allow dynamic-group database-resource-principal-dg to read autonomous-database-family in compartment ManagedCompartmentForPaaS
|
||||
|
||||
# Opcjonalnie, dla szerszego dostępu:
|
||||
Allow dynamic-group database-resource-principal-dg to use cloud-shell in tenancy
|
||||
```
|
||||
|
||||
4. Kliknij **Create**
|
||||
|
||||
## 3. Weryfikacja konfiguracji OCI
|
||||
|
||||
### 3.1 Sprawdzenie Dynamic Group
|
||||
|
||||
1. Przejdź do utworzonej Dynamic Group
|
||||
2. Sprawdź czy **Matching Instances** pokazuje Twoją instancję database
|
||||
3. Jeśli nie ma instancji, sprawdź reguły dopasowania
|
||||
|
||||
### 3.2 Test połączenia (opcjonalnie)
|
||||
|
||||
Jeśli masz dostęp SSH do compute instance:
|
||||
|
||||
```bash
|
||||
# Test dostępu do metadata service
|
||||
curl -H "Authorization: Bearer Oracle" \
|
||||
http://169.254.169.254/opc/v2/identity/cert.pem
|
||||
|
||||
# Jeśli zwraca certyfikat X.509, Resource Principal jest dostępny
|
||||
```
|
||||
|
||||
## 4. Konfiguracja w Oracle Database
|
||||
|
||||
### 4.1 Uruchomienie skryptu konfiguracyjnego
|
||||
|
||||
Wykonaj skrypt `configure_resource_principal.sql` utworzony wcześniej:
|
||||
|
||||
```sql
|
||||
-- Połącz się jako ADMIN
|
||||
@configure_resource_principal.sql
|
||||
```
|
||||
|
||||
### 4.2 Ręczna konfiguracja (alternatywa)
|
||||
|
||||
Jeśli skrypt automatyczny nie zadziała:
|
||||
|
||||
```sql
|
||||
-- Połącz się jako ADMIN
|
||||
CONNECT ADMIN/[password]@[service_name]
|
||||
|
||||
-- Sprawdź czy OCI$RESOURCE_PRINCIPAL jest dostępny
|
||||
SELECT credential_name FROM user_credentials
|
||||
WHERE credential_name = 'OCI$RESOURCE_PRINCIPAL';
|
||||
|
||||
-- Jeśli nie istnieje, utwórz własny:
|
||||
BEGIN
|
||||
DBMS_CLOUD.CREATE_CREDENTIAL(
|
||||
credential_name => 'OCI_RESOURCE_PRINCIPAL',
|
||||
username => '', -- Pusty dla Resource Principal
|
||||
password => '' -- Pusty dla Resource Principal
|
||||
);
|
||||
END;
|
||||
/
|
||||
```
|
||||
|
||||
### 4.3 Test konfiguracji
|
||||
|
||||
```sql
|
||||
-- Test listowania obiektów w Object Storage
|
||||
SELECT object_name
|
||||
FROM DBMS_CLOUD.LIST_OBJECTS(
|
||||
credential_name => 'OCI$RESOURCE_PRINCIPAL', -- lub 'OCI_RESOURCE_PRINCIPAL'
|
||||
location_uri => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/frtgjxu7zl7c/'
|
||||
)
|
||||
WHERE ROWNUM <= 5;
|
||||
```
|
||||
|
||||
## 5. Konfiguracja dla schematów aplikacji
|
||||
|
||||
### 5.1 Nadanie uprawnień
|
||||
|
||||
```sql
|
||||
-- Jako ADMIN, nadaj uprawnienia schematom aplikacji
|
||||
GRANT EXECUTE ON DBMS_CLOUD TO ODS;
|
||||
GRANT EXECUTE ON DBMS_CLOUD TO CT_MRDS;
|
||||
|
||||
-- Jeśli używasz własnego credential, nadaj dostęp:
|
||||
-- GRANT READ ON CREDENTIAL OCI_RESOURCE_PRINCIPAL TO ODS;
|
||||
```
|
||||
|
||||
### 5.2 Test z schematu aplikacji
|
||||
|
||||
```sql
|
||||
-- Połącz się jako ODS
|
||||
CONNECT ODS/[password]@[service_name]
|
||||
|
||||
-- Test wywołania
|
||||
EXEC FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE('TEST_TABLE', 'https://...', 'OCI$RESOURCE_PRINCIPAL');
|
||||
```
|
||||
|
||||
## 6. Aktualizacja kodu aplikacji
|
||||
|
||||
### 6.1 Aktualizacja FILE_MANAGER
|
||||
|
||||
Zaktualizuj kod aby użyć Resource Principal:
|
||||
|
||||
```sql
|
||||
-- W procedurze CREATE_EXTERNAL_TABLE
|
||||
-- Zmień z:
|
||||
v_credential_name := 'OCI_RESOURCE_PRINCIPAL';
|
||||
|
||||
-- Na:
|
||||
v_credential_name := 'OCI$RESOURCE_PRINCIPAL'; -- Jeśli dostępny
|
||||
```
|
||||
|
||||
### 6.2 Konfiguracja ENV_MANAGER
|
||||
|
||||
Dodaj konfigurację do tabeli A_FILE_MANAGER_CONFIG:
|
||||
|
||||
```sql
|
||||
INSERT INTO A_FILE_MANAGER_CONFIG (
|
||||
CONFIG_KEY,
|
||||
CONFIG_VALUE,
|
||||
DESCRIPTION
|
||||
) VALUES (
|
||||
'DEFAULT_CREDENTIAL_NAME',
|
||||
'OCI$RESOURCE_PRINCIPAL',
|
||||
'Default OCI credential for Resource Principal authentication'
|
||||
);
|
||||
```
|
||||
|
||||
## 7. Rozwiązywanie problemów
|
||||
|
||||
### 7.1 Sprawdzenie statusu Dynamic Group
|
||||
|
||||
```sql
|
||||
-- W SQL Developer Web lub SQLcl:
|
||||
SELECT
|
||||
DBMS_CLOUD.GET_OBJECT(
|
||||
credential_name => 'OCI$RESOURCE_PRINCIPAL',
|
||||
object_uri => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/frtgjxu7zl7c/b/data/o/test.txt'
|
||||
) as content
|
||||
FROM dual;
|
||||
```
|
||||
|
||||
### 7.2 Typowe błędy
|
||||
|
||||
| Błąd | Przyczyna | Rozwiązanie |
|
||||
|------|-----------|-------------|
|
||||
| `ORA-20407: Invalid Credentials` | Dynamic Group nie zawiera instancji | Sprawdź reguły dopasowania w Dynamic Group |
|
||||
| `ORA-20421: Object not found` | Brak uprawnień IAM | Sprawdź Policy dla Dynamic Group |
|
||||
| `OCI$RESOURCE_PRINCIPAL not found` | Resource Principal nie skonfigurowany | Użyj własnego credential lub skonfiguruj ponownie |
|
||||
|
||||
### 7.3 Weryfikacja uprawnień
|
||||
|
||||
```sql
|
||||
-- Sprawdź jakie credentials są dostępne
|
||||
SELECT credential_name, username
|
||||
FROM user_credentials
|
||||
ORDER BY credential_name;
|
||||
|
||||
-- Sprawdź uprawnienia DBMS_CLOUD
|
||||
SELECT grantee, privilege
|
||||
FROM user_tab_privs
|
||||
WHERE table_name = 'DBMS_CLOUD';
|
||||
```
|
||||
|
||||
## 8. Zalecenia bezpieczeństwa
|
||||
|
||||
1. **Minimalne uprawnienia**: Nadaj tylko niezbędne uprawnienia w IAM Policy
|
||||
2. **Monitoring**: Monitoruj użycie Resource Principal w OCI Audit
|
||||
3. **Rotacja**: Resource Principal automatycznie rotuje certyfikaty
|
||||
4. **Scope**: Ogranicz Dynamic Group do konkretnych instancji, nie całego compartment
|
||||
|
||||
## 9. Następne kroki
|
||||
|
||||
Po skonfigurowaniu Resource Principal:
|
||||
|
||||
1. Przetestuj wszystkie operacje FILE_MANAGER
|
||||
2. Zaktualizuj dokumentację aplikacji
|
||||
3. Skonfiguruj monitoring użycia Object Storage
|
||||
4. Rozważ implementację dla innych schematów
|
||||
|
||||
## 10. Referencje
|
||||
|
||||
- [Oracle Cloud Infrastructure Resource Principal Documentation](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm)
|
||||
- [DBMS_CLOUD Package Documentation](https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/dbms-cloud-package.html)
|
||||
- [Dynamic Groups Configuration](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm)
|
||||
Reference in New Issue
Block a user