Trebuie să recunoaștem că de fiecare dată când am planificat un upgrade, o migrare, ori o altă schimbare software sau hardware a sistemului am fost îngrijorați cu privire la comportamentul bazei de date. Această problemă nu ar mai trebui să ii îngrijoreze pe cei care au activată opțiunea Real Application Testing disponibilă în versiunea Enterprise a bazelor de date Oracle începând cu versiunea 11g Release 1. Database replay permite capturarea unui volum de lucru pe un sistem și repetarea acestuia pe același sistem ori pe un altul păstrând aceleași caracteristici. Iar acest lucru se poate face în diverse simulări până când rezultatul este satisfăcător astfel încât dorim să operăm aceeași modificare și pe sistemul de producție.
Procesul presupune patru faze pe care le voi detalia în rândurile ce urmează:
- Workload capture
- Workload pre-processing
- Workload replay
- Analiza datelor și raportarea
Pentru exemplu meu am folosit o distribuție Oracle Linux 6.8 cu update-urile la zi iar baza de date a fost Oracle 11.2.0.4 cu PSU din octombrie 2016 (11.2.0.4.161018) datele capturate le-am replicat pe o mașină cu Oracle Linux 7.3 bineînțeles cu toate update-urile împreună cu recent lansata baza de date Oracle 12.2.0.1. Trebuie menționat că hardware-ul bazei de date 12c este mai slab deci nu a fost o surpriză pentru mine să constat că timpul de procesare al datelor a fost mai mare decât cel de pe sistemul de unde am capturat datele.
Toți pașii de mai jos pot fi realizați cu ajutorul interfeței din Enterprise Manager, eu am preferat sa fac acest test din sqlplus iar comenzile executate sunt în rândurile următoare împreună cu comentariile mele.
Prima fază presupune capturarea workload-ului iar pentru acest lucru avem nevoie de un director la nivelul file system-ului unde Oracle are permisiunea să scrie în plus mai avem nevoie de un scenariu de test, pentru asta eu am folosit o procedură PL/SQL care generează multe update-uri în schema SH.
SQL> CREATE OR REPLACE DIRECTORY dbcapture AS '/opt/oracle/admin/orcl/capture'; Directory created.
Eu am ales să creez un filtru pentru a captura doar workload-ul generat de utilizatorul SH
SQL>EXEC dbms_workload_capture.add_filter('SH user','USER','SH'); PL/SQL procedure successfully completed. SQL>SELECT * FROM dba_workload_filters; TYPE ID STATUS SET_NAME NAME ATTRIBUTE VALUE ---------- ---------- ---------- -------------------- -------------------- ---------- ------------------------------ CAPTURE NEW SH USER USER SH
Cu ajutorul procedurii DBMS_WORKLOAD_CAPTURE.START_CAPTURE putem inițializa parametrul DURATION iar dacă nu este specificat captura se va opri după apelarea DBMS_WORKLOAD_CAPTURE.FINISH_CAPTURE. Cu ajutorul unui alt parametru CAPTURE_STS se poate genera SQL tuning set în paralel cu capturarea workload-ului.
SQL>EXEC DBMS_WORKLOAD_CAPTURE.START_CAPTURE(name => 'SH capture', dir => 'DBCAPTURE', default_action => 'EXCLUDE'); PL/SQL procedure successfully completed. SQL>SELECT name,DIRECTORY,status,filters_used FROM DBA_WORKLOAD_CAPTURES; NAME DIRECTORY STATUS FILTERS_USED -------------------- -------------------- ------------------------- ------------ SH capture DBCAPTURE IN PROGRESS 1
Acum rulez procedura cu utilizatorul SH generând un volum de încărcare pe baza de date:
SQL> show user USER is "SH" SQL> exec DBMS_OUTPUT.ENABLE (buffer_size => NULL); DECLARE i NUMBER; random_id NUMBER; maxid NUMBER; stmt VARCHAR2(100); BEGIN SELECT NVL(MAX(CUST_ID),0) INTO maxid FROM sh.customers; FOR i IN 1..10000000 LOOP random_id:=ROUND(DBMS_RANDOM.VALUE(1,maxid)); DBMS_OUTPUT.PUT_LINE('UPDATE sh.customers SET CUST_FIRST_NAME=dbms_random.string(''L'', 20) WHERE CUST_ID=' || random_id || ';'); UPDATE sh.customers SET CUST_FIRST_NAME=dbms_random.string('L', 20) WHERE CUST_ID=random_id; END LOOP; COMMIT; END;
După ce s-a terminat de rulat procedura oprim captura workload-ului cu DBMS_WORKLOAD_CAPTURE.FINISH_CAPTURE
SQL> show user USER is "SYS" SQL> EXEC DBMS_WORKLOAD_CAPTURE.FINISH_CAPTURE(timeout => 0, reason => 'Load test over'); PL/SQL procedure successfully completed.
Se poate observa că status-ul s-a modificat:
SQL>SELECT * FROM dba_workload_filters; TYPE ID STATUS SET_NAME NAME ATTRIBUTE VALUE ---------- ---------- ---------- -------------------- -------------------- ---------- ------------------------------ CAPTURE 2 USED SH USER USER SH SQL>SELECT ID,name,DIRECTORY,status,filters_used FROM DBA_WORKLOAD_CAPTURES; ID NAME DIRECTORY STATUS FILTERS_USED ------- -------------------- -------------------- ---------- ------------ 2 SH capture DBCAPTURE COMPLETED 1
Putem genera un raport al capturii cu ajutorul următoarei interogări:
SELECT dbms_workload_capture.report(2,'TEXT') as REP FROM dual;
Capturarea workload-ului s-a terminat și putem observa că în directorul specificat mai devreme sunt generate fișierele care vor trebui copiate pe sistemul în care dorim să replicăm workload-ul:
[oracle@localhost capture]$ ll * cap: total 324 -rw-r--r--. 1 oracle oinstall 31386 Mar 22 07:20 wcr_cr.html -rw-r--r--. 1 oracle oinstall 11344 Mar 22 07:20 wcr_cr.text -rw-r--r--. 1 oracle oinstall 276216 Mar 22 07:20 wcr_cr.xml -rw-r--r--. 1 oracle oinstall 240 Mar 22 07:20 wcr_fcapture.wmd -rw-r--r--. 1 oracle oinstall 115 Mar 22 07:01 wcr_scapture.wmd capfiles: total 4 drwxr-xr-x. 12 oracle oinstall 4096 Mar 22 07:01 inst1
Următoarele faze de pre-procesare, replay și analiza se vor realiza pe cel de-al doilea sistem după ce am copiat fișierele generate mai devreme. Pentru a mă asigura că voi putea repeta testul exact în aceleași condiții eu prefer să creez un restore point înainte iar la terminarea testului restaurez rapid baza exact la momentul de dinainte de a începe.
SQL> create restore point before_replay guarantee flashback database; Restore point created.
Directorul va trebui creat în aceeași locație unde sunt copiate fișierele generate de captură:
SQL> CREATE OR REPLACE DIRECTORY dbcapture AS '/opt/oracle/admin/orcl/capture'; Directory created.
In faza de pre-procesare sunt create toate metadatele necesare testului, în funcție de mărimea capturii această fază poate fi costisitoare ca timp și resurse.
SQL> EXEC DBMS_WORKLOAD_REPLAY.PROCESS_CAPTURE(capture_dir => 'DBCAPTURE'); PL/SQL procedure successfully completed.
O dată cu inițializarea workload-ului care a fost procesat mai devreme se începe faza de replay :
SQL> EXEC DBMS_WORKLOAD_REPLAY.INITIALIZE_REPLAY(replay_name => 'SH replay', replay_dir => 'DBCAPTURE'); PL/SQL procedure successfully completed. SQL> SELECT name,DIRECTORY,status FROM dba_workload_replays; NAME DIRECTORY STATUS -------------------- -------------------- ---------------------------------------- SH replay DBCAPTURE INITIALIZED
Identic cu procedura DBMS_WORKLOAD_CAPTURE.START_CAPTURE unde puteam seta parametrul CAPTURE_STS se poate realiza același lucru și la rularea DBMS_WORKLOAD_REPLAY.PREPARE_REPLAY acestă proprietate ajutându-ne să găsim soluții pentru îmbunătățirea performantei. In exemplu meu nu voi folosi această proprietate dar este bine de știu că există.
SQL> EXEC DBMS_WORKLOAD_REPLAY.PREPARE_REPLAY(); PL/SQL procedure successfully completed. SQL> SELECT name,DIRECTORY,status FROM dba_workload_replays; NAME DIRECTORY STATUS -------------------- -------------------- ---------------------------------------- SH replay DBCAPTURE PREPARE
Cu ajutorul tool-ului wrc din $ORACLE_HOME/bin rulăm testul efectiv dar înainte folosim parametrul mode=calibrate pentru a estima numărul de clienți și resursele necesare:
[oracle@localhost capture]$ wrc replaydir=/opt/oracle/admin/orcl/capture mode=calibrate Workload Replay Client: Release 12.2.0.1.0 - Production on Thu Mar 23 09:59:57 2017 Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved. Report for Workload in: /opt/oracle/admin/orcl/capture ----------------------- Recommendation: Consider using at least 1 clients divided among 1 CPU(s) You will need at least 3 MB of memory per client process. If your machine(s) cannot match that number, consider using more clients. Workload Characteristics: - max concurrency: 1 sessions - total number of sessions: 1 Assumptions: - 1 client process per 100 concurrent sessions - 4 client processes per CPU - 256 KB of memory cache per concurrent session - think time scale = 100 - connect time scale = 100 - synchronization = TRUE
După ce am determinat necesarul de resurse rulăm într-o altă sesiune shell clientul wrc iar dacă este nevoie pornim mai multi clienți, în exemplul meu am folosit unul singur:
[oracle@localhost capture]$ wrc system/oracle replaydir=/opt/oracle/admin/orcl/capture Workload Replay Client: Release 12.2.0.1.0 - Production on Thu Mar 23 10:03:41 2017 Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved. Wait for the replay to start (10:03:41) Înapoi în sesiunea din sqlplus pornim cu ajutorul lui DBMS_WORKLOAD_REPLAY.START_REPLAY: SQL> EXEC DBMS_WORKLOAD_REPLAY.START_REPLAY(); PL/SQL procedure successfully completed. SQL> SELECT name,DIRECTORY,status FROM dba_workload_replays; NAME DIRECTORY STATUS -------------------- -------------------- ---------------------------------------- SH replay DBCAPTURE IN PROGRESS
După ce testul s-a încheiat putem observa că status-ul din dba_workload_replays a devenit completed
SQL> SELECT name,DIRECTORY,status FROM dba_workload_replays; NAME DIRECTORY STATUS -------------------- -------------------- ---------------------------------------- SH replay DBCAPTURE COMPLETED
Iar în clientul sau clienții wrc este afișat:
Wait for the replay to start (10:03:41) Replay client 1 started (10:04:08) Replay client 1 finished (10:06:31)
In final tot testul nu ar fi concludent dacă nu am avea la dispoziție un raport în care este prezentat rezumatul testului. Pentru generarea raportului am folosit dbms_workload_replay.report. Voi afișa un exemplu al acestui raport pentru a vă forma o idee cu privire la informațiile pe care le puteți regăsi în acesta:
SQL> select dbms_workload_replay.report (replay_id => 1, format=> 'TEXT') from dual; "DB Replay Report for SH replay --------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------- | DB Name | DB Id | Release | RAC | Replay Name | Replay Status | ------------------------------------------------------------------------- | ORCL | 1467156416 | 12.2.0.1.0 | NO | SH replay | COMPLETED | ------------------------------------------------------------------------- Replay Information --------------------------------------------------------------------------------------------- | Information | Replay | Capture | --------------------------------------------------------------------------------------------- | Name | SH replay | SH capture | --------------------------------------------------------------------------------------------- | Status | COMPLETED | COMPLETED | --------------------------------------------------------------------------------------------- | Database Name | ORCL | ORCL | --------------------------------------------------------------------------------------------- | Database Version | 12.2.0.1.0 | 11.2.0.4.0 | --------------------------------------------------------------------------------------------- | Start Time | 24-03-17 07:42:22 | 23-03-17 15:34:49 | --------------------------------------------------------------------------------------------- | End Time | 24-03-17 08:07:33 | 23-03-17 15:52:20 | --------------------------------------------------------------------------------------------- | Duration | 25 minutes 11 seconds | 17 minutes 31 seconds | --------------------------------------------------------------------------------------------- | Directory Object | DBCAPTURE | DBCAPTURE | --------------------------------------------------------------------------------------------- | Directory Path | /opt/oracle/admin/orcl/capture | /opt/oracle/admin/orcl/capture | --------------------------------------------------------------------------------------------- | AWR DB Id | 1467156416 | | --------------------------------------------------------------------------------------------- | AWR Begin Snap Id | 2 | | --------------------------------------------------------------------------------------------- | AWR End Snap Id | 3 | | --------------------------------------------------------------------------------------------- | PL/SQL Capture Mode | TOP_LEVEL | TOP_LEVEL | --------------------------------------------------------------------------------------------- | Replay Directory Number | 672159336 | | --------------------------------------------------------------------------------------------- | Replay Schedule Name | | | --------------------------------------------------------------------------------------------- Replay Options --------------------------------------------------------- | Option Name | Value | --------------------------------------------------------- | Synchronization | SCN | --------------------------------------------------------- | Connect Time | 100% | --------------------------------------------------------- | Think Time | 100% | --------------------------------------------------------- | Think Time Auto Correct | TRUE | --------------------------------------------------------- | Number of WRC Clients | 1 (1 Completed, 0 Running ) | --------------------------------------------------------- Replay Statistics ---------------------------------------------------------------- | Statistic | Replay | Capture | ---------------------------------------------------------------- | DB Time | 1528.207 seconds | 618.851 seconds | ---------------------------------------------------------------- | PL/SQL DB Time | 1496.470 seconds | 0.000 seconds | ---------------------------------------------------------------- | Average Active Sessions | 1.01 | .59 | ---------------------------------------------------------------- | User calls | 21 | 21 | ---------------------------------------------------------------- | PL/SQL user calls | 3 | 0 | ---------------------------------------------------------------- | PL/SQL subcalls | 0 | 0 | ---------------------------------------------------------------- Replay Divergence Summary ------------------------------------------------------------------- | Divergence Type | Count | % Total | ------------------------------------------------------------------- | Session Failures During Replay | 0 | 0.00 | ------------------------------------------------------------------- | Errors No Longer Seen During Replay | 0 | 0.00 | ------------------------------------------------------------------- | New Errors Seen During Replay | 0 | 0.00 | ------------------------------------------------------------------- | Errors Mutated During Replay | 0 | 0.00 | ------------------------------------------------------------------- | DMLs with Different Number of Rows Modified | 0 | 0.00 | ------------------------------------------------------------------- | SELECTs with Different Number of Rows Fetched | 0 | 0.00 | ------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- Workload Profile Top Events ------------------------------------------------------------------- | Event | Event Class | % Activity | ------------------------------------------------------------------- | log file switch (archiving needed) | Configuration | 12.06 | ------------------------------------------------------------------- | CPU + Wait for CPU | CPU | 10.45 | ------------------------------------------------------------------- | db file sequential read | User I/O | 0.80 | ------------------------------------------------------------------- | latch: shared pool | Concurrency | 0.16 | ------------------------------------------------------------------- | Disk file operations I/O | User I/O | 0.16 | ------------------------------------------------------------------- Top Service/Module/Action --------------------------------------------------------------------------------------------------- | Service Name | Module Name | % Activity | Action Drilldown | --------------------------------------------------------------------------------------------------- | SYS$USERS | SQL*Plus | 23.79 | ----------------------------------------------------- | | | | | | Action Name | % Activity | | | | | | ----------------------------------------------------- | | | | | | UNNAMED | 23.79 | | | | | | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------- Top SQL with Top Events --------------------------------------------------------------------------------------------------- | SQL ID | Planhash | Sampled Number of | % Activity | Event Drilldown | | | | Executions | | | --------------------------------------------------------------------------------------------------- | c79rudfpp32nk | 3828985807 | 42 | 18.97 | ------------------------- | | | | | | | Event | % | | | | | | | | | Activity | | | | | | | ------------------------- | | | | | | | log file | 12.06 | | | | | | | | switch (a | | | | | | | | | rchiving | | | | | | | | | needed) | | | | | | | | ------------------------- | | | | | | | CPU + | 6.59 | | | | | | | | Wait for | | | | | | | | | CPU | | | | | | | | ------------------------- | | | | | | | Disk file | 0.16 | | | | | | | | operation | | | | | | | | | s I/O | | | | | | | | ------------------------- | | | | | | | control | 0.16 | | | | | | | | file | | | | | | | | | parallel | | | | | | | | | write | | | | | | | | ------------------------- | --------------------------------------------------------------------------------------------------- | 51r1m402vd1ks | 3407352264 | 12 | 2.09 | ------------------------- | | | | | | | Event | % | | | | | | | | | Activity | | | | | | | ------------------------- | | | | | | | CPU + | 1.29 | | | | | | | | Wait for | | | | | | | | | CPU | | | | | | | | ------------------------- | | | | | | | db file s | 0.80 | | | | | | | | equential | | | | | | | | | read | | | | | | | | ------------------------- | --------------------------------------------------------------------------------------------------- | 8wn1cj9cvkfjs | 0 | 1 | 2.09 | ------------------------- | | | | | | | Event | % | | | | | | | | | Activity | | | | | | | ------------------------- | | | | | | | CPU + | 2.09 | | | | | | | | Wait for | | | | | | | | | CPU | | | | | | | | ------------------------- | --------------------------------------------------------------------------------------------------- Top Sessions with Top Events -------------------------------------------------------------------------------------------------- | Session ID | Session Serial | Username | Program | % Activity | Event Drilldown | -------------------------------------------------------------------------------------------------- | 34 | 15416 | SH | wrc@localhost.loc | 23.79 | ----------------- | | | | | aldomain (TNS | | | Event | % Act | | | | | | V1-V3) | | | | ivity | | | | | | | | ----------------- | | | | | | | | log | 12.06 | | | | | | | | | file | | | | | | | | | | switc | | | | | | | | | | h (ar | | | | | | | | | | chivi | | | | | | | | | | ng ne | | | | | | | | | | eded) | | | | | | | | | ----------------- | | | | | | | | CPU + | 10.45 | | | | | | | | | Wait | | | | | | | | | | for | | | | | | | | | | CPU | | | | | | | | | ----------------- | | | | | | | | db | 0.80 | | | | | | | | | file | | | | | | | | | | seque | | | | | | | | | | ntial | | | | | | | | | | read | | | | | | | | | ----------------- | | | | | | | | Disk | 0.16 | | | | | | | | | file | | | | | | | | | | opera | | | | | | | | | | tions | | | | | | | | | | I/O | | | | | | | | | ----------------- | | | | | | | | contr | 0.16 | | | | | | | | | ol | | | | | | | | | | file | | | | | | | | | | paral | | | | | | | | | | lel | | | | | | | | | | write | | | | | | | | | ----------------- | -------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- Replay Divergence Session Failures By Application -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- Error Divergence By Application -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- By SQL -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- DML Data Divergence By Application -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- By SQL -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- By Divergence magnitude -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- SELECT Data Divergence By Application -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- By Divergence magnitude -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- --------------------------------------------------------------------------------------------------- Replay Clients Alerts -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- Replay Filters -------------------------------------------------- | No data exists for this section of the report. | -------------------------------------------------- End of Report."