SET SERVEROUTPUT ON;
-- Step 1: Drop and recreate tables to ensure correct structure
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE tablespace_control';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -942 THEN NULL;
ELSE RAISE;
END IF;
END;
/
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE tablespace_log';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -942 THEN NULL;
ELSE RAISE;
END IF;
END;
/
BEGIN
EXECUTE IMMEDIATE q'[
CREATE TABLE tablespace_control (
tablespace_name VARCHAR2(30) PRIMARY KEY,
initial_size_gb NUMBER NOT NULL,
status VARCHAR2(10) DEFAULT 'PENDING' CHECK (status IN ('PENDING', 'RUNNING', 'COMPLETED', 'FAILED')),
retry_count NUMBER DEFAULT 0,
last_attempt TIMESTAMP,
created_by VARCHAR2(30) DEFAULT USER,
CONSTRAINT chk_size_positive CHECK (initial_size_gb > 0)
)
]';
END;
/
BEGIN
EXECUTE IMMEDIATE q'[
CREATE TABLE tablespace_log (
log_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
tablespace_name VARCHAR2(30),
action VARCHAR2(20),
status VARCHAR2(10),
error_message VARCHAR2(4000),
log_time TIMESTAMP DEFAULT SYSTIMESTAMP,
session_user VARCHAR2(30) DEFAULT USER,
session_id NUMBER DEFAULT SYS_CONTEXT('USERENV', 'SID')
)
]';
END;
/
-- Step 2: Populate tablespace_control (replace with your 64 tablespaces)
BEGIN
INSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES ('TABLESPACE1', 6268);
INSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES ('TABLESPACE2', 3000);
INSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES ('TABLESPACE3', 2500);
-- Add remaining 61 tablespaces (e.g., from parse_tablespace_script.sql output)
-- Example loop for testing (comment out after replacing):
/*
FOR i IN 4..64 LOOP
INSERT INTO tablespace_control (tablespace_name, initial_size_gb)
VALUES ('TABLESPACE' || i, CASE WHEN MOD(i, 2) = 0 THEN 3000 ELSE 2000 END);
END LOOP;
*/
COMMIT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error populating tablespace_control: ' || SQLERRM);
RAISE;
END;
/
-- Step 3: Create tablespaces directly
DECLARE
v_common_clause CONSTANT VARCHAR2(500) := 'AUTOEXTEND ON NEXT 1G MAXSIZE UNLIMITED LOGGING DEFAULT NO INMEMORY ONLINE EXTENT MANAGEMENT LOCAL AUTOALLOCATE BLOCKSIZE 8K SEGMENT SPACE MANAGEMENT AUTO FLASHBACK ON';
v_max_retries CONSTANT NUMBER := 3;
v_batch_size CONSTANT NUMBER := 3; -- Smaller batch
v_processed NUMBER := 0;
v_sql VARCHAR2(1000);
v_error_msg VARCHAR2(4000);
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
FOR rec IN (
SELECT tablespace_name, initial_size_gb, retry_count
FROM tablespace_control
WHERE status IN ('PENDING', 'FAILED')
ORDER BY tablespace_name
) LOOP
DBMS_OUTPUT.PUT_LINE('Processing: ' || rec.tablespace_name || ', Size: ' || rec.initial_size_gb || ', Retry: ' || rec.retry_count);
-- Check if tablespace exists
DECLARE
v_exists NUMBER;
BEGIN
SELECT COUNT(*) INTO v_exists FROM DBA_TABLESPACES WHERE tablespace_name = rec.tablespace_name;
IF v_exists > 0 THEN
DBMS_OUTPUT.PUT_LINE('Inserting SKIP_EXISTS log for: ' || rec.tablespace_name);
UPDATE tablespace_control SET status = 'COMPLETED', last_attempt = SYSTIMESTAMP
WHERE tablespace_name = rec.tablespace_name;
INSERT INTO tablespace_log (tablespace_name, action, status)
VALUES (rec.tablespace_name, 'SKIP_EXISTS', 'COMPLETED');
COMMIT;
DBMS_OUTPUT.PUT_LINE('Skipped: ' || rec.tablespace_name || ' (already exists)');
CONTINUE;
END IF;
END;
-- Mark as RUNNING
DBMS_OUTPUT.PUT_LINE('Inserting RUNNING status for: ' || rec.tablespace_name);
UPDATE tablespace_control SET status = 'RUNNING', last_attempt = SYSTIMESTAMP
WHERE tablespace_name = rec.tablespace_name;
COMMIT;
-- Create tablespace
v_sql := 'CREATE BIGFILE TABLESPACE ' || DBMS_ASSERT.SQL_OBJECT_NAME(rec.tablespace_name) || ' DATAFILE SIZE ' || rec.initial_size_gb || 'G ' || v_common_clause;
BEGIN
DBMS_OUTPUT.PUT_LINE('Executing: ' || SUBSTR(v_sql, 1, 200) || '...');
EXECUTE IMMEDIATE v_sql;
DBMS_OUTPUT.PUT_LINE('Inserting COMPLETED log for: ' || rec.tablespace_name);
UPDATE tablespace_control SET status = 'COMPLETED', retry_count = 0, last_attempt = SYSTIMESTAMP
WHERE tablespace_name = rec.tablespace_name;
INSERT INTO tablespace_log (tablespace_name, action, status)
VALUES (rec.tablespace_name, 'CREATE', 'COMPLETED');
COMMIT;
DBMS_OUTPUT.PUT_LINE('Created: ' || rec.tablespace_name);
EXCEPTION
WHEN OTHERS THEN
v_error_msg := SQLERRM;
DBMS_OUTPUT.PUT_LINE('Inserting FAILED log for: ' || rec.tablespace_name);
UPDATE tablespace_control SET status = 'FAILED', retry_count = retry_count + 1, last_attempt = SYSTIMESTAMP
WHERE tablespace_name = rec.tablespace_name;
INSERT INTO tablespace_log (tablespace_name, action, status, error_message)
VALUES (rec.tablespace_name, 'CREATE', 'FAILED', v_error_msg);
COMMIT;
DBMS_OUTPUT.PUT_LINE('Failed: ' || rec.tablespace_name || ' - ' || v_error_msg);
IF rec.retry_count + 1 < v_max_retries THEN
DBMS_OUTPUT.PUT_LINE('Inserting AUTO_RETRY log for: ' || rec.tablespace_name);
INSERT INTO tablespace_log (tablespace_name, action, status)
VALUES (rec.tablespace_name, 'AUTO_RETRY', 'SCHEDULED');
COMMIT;
DBMS_OUTPUT.PUT_LINE('Scheduled retry for: ' || rec.tablespace_name);
END IF;
END;
-- Batch pause
v_processed := v_processed + 1;
IF MOD(v_processed, v_batch_size) = 0 THEN
DBMS_OUTPUT.PUT_LINE('Pausing for 180 seconds after batch of ' || v_batch_size);
DBMS_LOCK.SLEEP(180);
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Tablespace creation complete. Check tablespace_log for details.');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error in main loop: ' || SQLERRM);
END;
/
How to Use
Populate tablespace_control:- Use the output from parse_tablespace_script.sql (artifact ID a903bb09-da7e-470a-a396-623c177a7737) to insert your 64 tablespaces:sqlINSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES ('TABLESPACE1', 6268);INSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES ('TABLESPACE2', 3000);-- Add all 64COMMIT;
- Verify:sqlSELECT COUNT(*) FROM tablespace_control;
- Run the Script:
- In TOAD SQL Editor, execute the script with SET SERVEROUTPUT ON;.
- Output shows progress (e.g., Created: TABLESPACE1, Skipped: TABLESPACE2 (already exists), Failed: TABLESPACE3 - ORA-01658).
- The script skips existing tablespaces (SKIP_EXISTS), retries failures (3 times), and logs to tablespace_log.
- Mitigate TOAD Timeout:
- Batch size is reduced to 5 (v_batch_size = 5) with 120-second pauses (DBMS_LOCK.SLEEP(120)) to minimize session timeout risk.
- In TOAD, increase session timeout if possible (check “Database” > “Session” settings).
- If timeout occurs, re-run the script—it resumes from PENDING or FAILED tablespaces.
- Monitor:
- Check logs:sqlSELECT log_id, tablespace_name, action, status, error_message, log_timeFROM tablespace_logWHERE action IN ('CREATE', 'SKIP_EXISTS', 'AUTO_RETRY')ORDER BY log_time DESC;
- Check status:sqlSELECT tablespace_name, initial_size_gb, status, retry_count, last_attemptFROM tablespace_controlORDER BY tablespace_name;
- Verify tablespaces:sqlSELECT tablespace_name, bigfile, ROUND(bytes/1024/1024/1024, 2) AS size_gbFROM dba_tablespacesWHERE tablespace_name LIKE 'TABLESPACE%'ORDER BY tablespace_name;
- Check logs:
- Retry Failures:
- Reset failed tablespaces:sqlUPDATE tablespace_control SET status = 'PENDING', retry_count = 0 WHERE status = 'FAILED';COMMIT;
- Re-run the script.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
How to Use in Your Workflow
- Backup tablespace_control (Optional):
- Before deleting, save the current rows to restore later:sqlCREATE TABLE tablespace_control_backup AS SELECT * FROM tablespace_control;
- Or save INSERT statements:sqlSELECT 'INSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES (''' || tablespace_name || ''', ' || initial_size_gb || ');'FROM tablespace_control;
- Before deleting, save the current rows to restore later:
- Run the DELETE:
- Modify the DELETE statement with your desired tablespaces (e.g., first 10):sqlDELETE FROM tablespace_control WHERE tablespace_name NOT IN ('TABLESPACE1', 'TABLESPACE2', 'TABLESPACE3', ..., 'TABLESPACE10');COMMIT;
- Verify:sqlSELECT tablespace_name, initial_size_gb, status FROM tablespace_control;
- Modify the DELETE statement with your desired tablespaces (e.g., first 10):
- Run the Direct Execution Script:
- Execute create_multiple_tablespaces_direct.sql (version dc078ecc-90db-4e89-9e90-306d80616933) in TOAD with SET SERVEROUTPUT ON;.
- The script processes only the remaining tablespaces, skipping existing ones and logging SKIP_EXISTS.
- Monitor:
- Check logs:sqlSELECT log_id, tablespace_name, action, status, error_message, log_timeFROM tablespace_logWHERE action IN ('CREATE', 'SKIP_EXISTS', 'AUTO_RETRY')ORDER BY log_time DESC;
- Check status:sqlSELECT tablespace_name, initial_size_gb, status, retry_countFROM tablespace_control;
- Check logs:
- Add More Tablespaces:
- Repopulate tablespace_control for the next batch:sqlINSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES ('TABLESPACE11', 2000);-- Add next batchCOMMIT;
- Re-run the script.
- Repopulate tablespace_control for the next batch:
RDS-Specific Notes
- Timeout Risk: The direct script runs synchronously, so TOAD’s 1-hour timeout may interrupt large batches (e.g., 6268G tablespaces). The DELETE reduces this risk by limiting to 10 tablespaces. Adjust v_batch_size = 3and DBMS_LOCK.SLEEP(180) if needed.
- Storage: 10 tablespaces at ~3000G (~30 TB) is still significant. Check:Scale storage via AWS console if needed (max 64 TiB).sqlSELECT SUM(bytes)/1024/1024/1024 AS total_gb FROM dba_data_files;
- Privileges: Ensure:sqlGRANT CREATE TABLESPACE, CREATE TABLE TO your_username;
My Opinion
- Why DELETE Helps: Limiting to 10 tablespaces via DELETE is a practical way to manage TOAD timeouts while job_queue_processes = 0 awaits AWS Support resolution. It allows incremental progress without losing the skip-existing (SKIP_EXISTS) or retry functionality.
- Long-Term: Contact AWS Support to set job_queue_processes > 0 (e.g., 100) for true background execution using the original Scheduler script.
- Testing: Start with a small batch (e.g., 3 tablespaces at 1G) to confirm the script works:sqlTRUNCATE TABLE tablespace_control;INSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES ('TEST_TS_01', 1);INSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES ('TEST_TS_02', 1);INSERT INTO tablespace_control (tablespace_name, initial_size_gb) VALUES ('TEST_TS_03', 1);COMMIT;
If you provide your 64 tablespace names/sizes, I can generate the exact INSERT and DELETE statements for your batches!
No comments:
Post a Comment