=====Log File Handling im Oracle Real Application Cluster 12c/18c - die automatischen Funktionen der Datenbank ausnützen und anpassen==== **11g/12c/18c** Nach der erfolgreichen Installation einer Oracle Cluster Umgebung stellt sich bald die Frage, wie mit den ganzen Log Files des Clusters und der DB Umgebung umgehen? Welche Logfiles müssen regelmäßig und wie gelöscht werden? Was erfolgt schon bereits automatisch? * Alle Logs unter DIAG Home (ADR - Automatic Diagnostic Repository) * Audit Log der Datenbank in adump ---- ---- ====Audit Logs der Datenbank(en) ==== Die Datenbank schreibt bei jeden Login eines User mit "sysdba" Rechten noch eine sehr unpraktische kleine Log Datei. Das ist im Cluster sehr lästig, da auch interne SYS Verbindungen so auditiert werden und damit eine abstruse hohe Anzahl an Logdateien zusammen kommen. In machen Umgebung häufen sich da schnell mal im hohen hunderttausender Bereich Dateien an. Das hätte Oracle auch intelligenter lösen können. Die Datenbank kann diesen Bereich auch selber aufräumen, das muss aber konfiguriert werden => siehe [[dba:oracle_clean_audit_log_entries|Die Audit Logs der Datenbank unter Oracle 11g/12c mit DBMS_AUDIT_MGMT "aufräumen"]]. Und in einer Umgebung mit vom Kunden verwalteten, kritischen 24/7 Datenbank ist das dann organisatorisch auch nicht so einfach einzurichten. Und was ist aber mit der ASM Instance und der Management DB? Alternativ mit einem einfachen Script einfach selber löschen: #!/bin/sh # ###################################### # # Clean all audit log files # www.pipperr.de # see https://www.pipperr.de/dokuwiki/doku.php?id=dba:oracle_rac_logfile_handling # # ##################################### # Crontab # # M H D M # Oracle clean Audit Logs # 0 20 * * * /home/grid/scripts/cleanAuditLogs.sh > /tmp/crontab_start_clean_audit_log_job_grid.log # # ##################################### DIRECTORY=/opt/oracle/admin/* LOG_FILE=/tmp/aud_delete_logs_list_${USER}.log echo "Info - start to analyses directory : ${DIRECTORY} - start at -- `date` -- " > $LOG_FILE for d in $DIRECTORY do FILES=${d}/adump/*.aud TEST_DIR=${d}/adump echo "Info - +++++++++++++++++++++++++++++++++++++++++" >> $LOG_FILE echo "Info - check the directory : ${FILES} " >> $LOG_FILE if [ -d "${TEST_DIR}" ]; then # check the user for this home # Grid owner or DB owner FILE_META=($(ls -ld ${d} )) #OWNER FILE_OWNER="${FILE_META[2]}" echo "Info - Owner of ${d} is ${FILE_OWNER}" >> $LOG_FILE if [[ ${USER} = ${FILE_OWNER} ]]; then DATE_NOW_EPOCH=`date +%s` #Get the epoch 6 Month ago DATE_DELETE_OLDER=`date --date "now -6 months" +"%s"` echo "Info - Found `ls ${TEST_DIR} | wc -l` files in ${TEST_DIR}" >> $LOG_FILE echo "Info - check the age of the file - start at -- `date` -- " >> $LOG_FILE for f in $FILES do #File date as epoch FILE_DATE=`stat -c %Y ${f}` >> $LOG_FILE 2>&1 FILE_LOG_DATE=`stat -c %y ${f}` >> $LOG_FILE 2>&1 if [[ ${FILE_DATE} -lt ${DATE_DELETE_OLDER} ]]; then echo "Info - delete :: ${FILE_LOG_DATE} ${f}" >> $LOG_FILE rm ${f} >> $LOG_FILE 2>&1 fi done echo "Info - finish with ${FILES} at -- `date` -- " >> $LOG_FILE else echo "Warning - Can not delete files from other user ${FILE_OWNER} as user ${USER}" >> $LOG_FILE fi else echo "Warning - directory ${TEST_DIR} not exists" >> $LOG_FILE fi echo "Info - +++++++++++++++++++++++++++++++++++++++++" >> $LOG_FILE done echo "Info - finish at -- `date` -- " >> $LOG_FILE Aktuellste Version, siehe auch hier => https://github.com/gpipperr/OraPowerShell/blob/master/Ora_Bash_env_DB_backup/scripts/cleanAuditLogs.sh ---- ---- ==== ADR - Automatic Diagnostic Repository Logs ==== === Das ADR - Automatic Diagnostic Repository === Im ADR - Automatic Diagnostic Repository - legen inzwischen fast alle Oracle Produkte inkl. Cluster die meisten der Logfiles ab. In der Theorie werden Logfiles, die über das ADR Feature in das DIAG_HOME geschrieben werden, werden auch automatisch wieder gelöscht. In der Dokumentation steht aber auch ein Nebensatz, das diese nicht für alle Oracle Produkt gilt. Da ja auch ADR Job existiert, der regelmäßig löscht, muss das im jeweiligen Produkt implementiert werden. == Datenbank == In der Datenbank übernimmt das der MMON Prozess. Aus der Support Node "Which Files Are Part Of SHORTP_POLICY And LONGP_POLICY In ADR? (Doc ID 975448.1)" "For the database ADR, auto purge job, implemented as an mmon slave task, purges the expired data from ADR once in 7 days." Und wie oft? Aus der Support Node "Is there a way to control Auto_Purge Frequency done by the MMON ? (Doc ID 1446242.1)" The automatic purge cycle is designed as follows. (1) The first actual purge action will be 2 days after instance startup time (2) The next automatic purge actions following this first purge is done once every 7 days The auto-purge will ONLY purge every 7 days and this has always been the way it was designed. It then uses the SHORTP_POLICY and LONGP_POLICY values to determine how much information to purge. The ADR purge is run towards the end of the regular AWR purge. There is no control on the purge frequency, it is fixed to be 48 hours after startup and then every 7 days. Manual purge is the only way to control purge actions in between. Die Alert Log der DB im XML Format wird unter $DIAG_HOME/rdbms///alert abgelegt. Diese Datei wird rollierend, die log.xml unter alert wird nach 11MB rolliert und als log_.xml archiviert. Nachteil: die alte alert_.log gibt es immer noch, wie es aussieht wird diese aber nicht automatisch gelöscht! ==Listener und Cluster ab 12c == Hier bin ich noch am suchen was hier 12c/18c so automatisch durchgeführt, das Automatic Purge Datum ist bei meinen Umgebung leer. Evtl. ist da aber auch noch etwas einstellbar. ---- === DIAG HOME - ADR Base Analyse === == Wie groß ist das ganze? == # wie /opt/oracle/diag cd $DIAG_HOME du . -h --max-depth=1 ... ... 22G Und warum wird das dann auf jeden Cluster Knoten immer größer? == Wie lange werden Daten aufbewahrt == Im ADR wird pro ADR Home in zwei Policies hinterlegt wie lange die Daten aufbewahrt werden sollen. **SHORTP_POLICY** * Trace Files, Core Dumps / Packaging Informationen *TRACE *CDUMP *UTSCDMP *IPS * Default auf 720 Stunden (30 Tage) gesetzt **LONGP_POLICY.** * alert_.xml Dateien und Incidents * ALERT * INCIDENT * SWEEP * STAGE *HM * Default auf 8760 Stunden (365 Tage) gesetzt Die Kontrolle der Einstellung im jeweiligen Home erfolgt über "adrci": # Oracle Home setzen, sollte zur DB Version passen! adrci adrci> show homes adrci> set home diag/rdbms/gipdb/GPIDB1 adrci> show control ADR Home = /opt/oracle/diag/rdbms/gipdb/GPIDB1: ************************************************************************* ADRID SHORTP_POLICY LONGP_POLICY LAST_MOD_TIME -------------------- -------------------- -------------------- ---------------------------------------- 1692434021 720 8760 2016-04-05 20:39:04.459711 +02:00 LAST_AUTOPRG_TIME LAST_MANUPRG_TIME ---------------------------------------- ---------------------------------------- 2019-02-16 05:42:43.630938 +01:00 2016-04-09 16:59:02.440624 +02:00 ADRDIR_VERSION ADRSCHM_VERSION ADRSCHMV_SUMMARY ADRALERT_VERSION CREATE_TIME -------------------- -------------------- -------------------- -------------------- ---------------------------------------- 1 2 80 1 2016-04-05 20:39:04.459711 +02:00 1 rows fetched # im Detail können die einzelnen Parameter auch einzeln abgefragt werden: adrci> select SHORTP_POLICY,LONGP_POLICY from ADR_CONTROL; ADR Home = /opt/oracle/diag/rdbms/gipdb/GPIDB1: ************************************************************************* SHORTP_POLICY LONGP_POLICY -------------------- -------------------- 720 8760 1 rows fetched # Prüfen ob wann das das letzte mal durchgeführt wurde adrci> select LAST_AUTOPRG_TIME from ADR_CONTROL; ************************************************************************* LAST_AUTOPRG_TIME ---------------------------------------- 2019-02-16 05:42:43.630938 +01:00 1 rows fetched ---- === Policies anpassen === Mit adrci im entsprechenden Home setzen: #Auf 183 Tage setzen adrci> set control (LONGP_POLICY=4392) ; ---- === Test und Analyse, ob das auch klappt === Nachdem wir die Einstellungen kennen, Default ist ein Jahr, sollten wir ja keine Daten vor dem 2018-02-16 finden, wenn LAST_AUTOPRG_TIME in dem Home eine Wert von heute aufweist. Test mit: cd /opt/oracle/diag/rdbms/gipdb find . -type f -mtime +365 -exec ls -la {} \; ... -rw-r----- 1 oracle asmadmin 64K Apr 8 2016 ./metadata/IPS_PACKAGE_UNPACK_HISTORY.ams -rw-r----- 1 oracle asmadmin 0 Apr 8 2016 ./lck/AM_3216668543_3129272988.lck ... Abzählen: find . -type f -mtime +365 -exec ls -la {} \; | grep -v "/lck/" | grep -v ".ams" | wc -l Im großen und ganzen scheint das zu klappen, nur die ADRCI Metadaten und die ein paar lock files sind noch da. Da in allen Homes eigentlich das gleiche eingestellt sein sollte, sollte da dann ja auch für clients und CRS Home / ASM Home stimmen. Eine Suche über eine mittelgroße Cluster Umgebung zeigt aber "40975" Datei die älter sind. Warum ist das so? Zuerst in alle Home prüfen was eingestellt ist und wann zuletzt ein Auto Purge statt fand: #!/bin/sh # check all home settings # echo "Start to check all home settings" for a in $(adrci exec="show homes" | grep diag) do echo "check home setting for ${a}" adrci exec="set home ${a};select SHORTP_POLICY,LONGP_POLICY,LAST_AUTOPRG_TIME from ADR_CONTROL;" done echo "finsh" In den Homes in dem LAST_AUTOPRG_TIME Null ist und die Daten älter als ein Jahr ist, muss dann wohl von Hand gelöscht werden. Bei der Management DB prüfen, ob die überhaupt noch auf diesem Knoten läuft, dann löscht ja auch niemand jemals etwas! ---- === Job um automatisch zu löschen === Script Fragment: #!/bin/sh # ###################################### # # Purge DIAG HOMES # www.pipperr.de # see https://www.pipperr.de/dokuwiki/doku.php?id=dba:oracle_rac_logfile_handling # # ##################################### # Crontab # # M H D M # Oracle purge DIAG Logs # 0 20 * * * /home/grid/scripts/cleanDiagHome.sh > /tmp/crontab_start_clean_diag_home_job_grid.log # # ##################################### #set the enviroment to the ${USER} home source /home/${USER}/.profile # set the home switch to the current user! # Set this for each installation setdb 1 > /dev/null 2>&1 # Fill out the diag home # Set this for each installation DIAG_HOME=/opt/oracle/ # write log LOG_FILE=/tmp/diag_delete_log_${USER}.log # set rentation policy days # 263520= 183 days # Set this for each installation MINUTES=263520 echo "Info - start to analyses all DIAG Homes - start at -- `date` -- " > $LOG_FILE echo "Info - clean all 12c homes after for files older than ${MINUTES} minutes" >> $LOG_FILE for a in $(adrci exec="show homes" | grep diag) do echo "Info - Info purge Log for Home ${a}" >> $LOG_FILE # check the user for this home # Grid owner or DB owner FILE_META=($(ls -ld $DIAG_HOME/${a} )) #OWNER FILE_OWNER="${FILE_META[2]}" echo "Info - Owner of ${a} is ${FILE_OWNER}" >> $LOG_FILE if [[ ${USER} = ${FILE_OWNER} ]]; then adrci exec="set home ${a}; purge -age ${MINUTES} ;" >> $LOG_FILE 2>&1 else echo "Warning - Can not clean ADR files from other user ${FILE_OWNER} as user ${USER}" >> $LOG_FILE fi done echo "Info - finish at -- `date` -- " >> $LOG_FILE Aktuellste Version siehe hier => https://github.com/gpipperr/OraPowerShell/blob/master/Ora_Bash_env_DB_backup/scripts/cleanDiagHome.sh (Achtung, falls Ihr das Script kopiert, müsste Ihr die Oracle Home Umgebung manuell setzen oder .profile von mir verwenden) Das funktioniert aber NUR wenn alle ADRCI auch kompatible zum gesetzten Oracle Home sind! In meiner Umgebung sind alle ADR Homes auf 12c R2 NUR die DB Homes nicht! Nicht das dann die DB Problem bekommt Ihre eigenen Logfiles zu schreiben! D.h. wir brauchen noch eine Variante um das entsprechende Home zu setzen! Und die User Rechte im Cluster müssen auch noch passen! ---- ===Von Hand löschen == Manuell wird mit "purge -age <älter_als_minuten>" gelöscht. siehe dazu auch => https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sutil/oracle-adr-command-interpreter-adrci.html#GUID-92DD451B-C3A1-48D7-A147-3296E75572CB Die Angabe erfolgt in Minuten! => Ein halbes Jahr ist dann "select round(365/2)*24*60 from dual" => 263520 #auf den richtigen Oracle User für das DB Home achten! hier GRID! # Oracle Home auf das Produkt setzen, das auch das Log angelegt hat hier das Cluster! adrci adrci> show homes ADR Homes: diag/rdbms/_mgmtdb/-MGMTDB adrci> purge -age 0 adrci> exit # prüfen du . -h 644M ./trace .. 650M # Alert Log zurücksetzen #prüfen ob die DB wirklich nicht läut ps -uafx | grep smon cd ./trace echo -- > alert_-MGMTDB.log du . -h .. 5.2M Alles löschen das älter als ein halbes Jahr ist: # ales älter als ein halbes Jahr löschen purge -age 263520 Script Fragment dazu: echo "Manually Purge all Homes to 183 days = 263520 minutes" for a in $(adrci exec="show homes" | grep diag) do echo "check home setting for ${a}" adrci exec="set home ${a};purge -age 263520;" done echo "finsh" == Problem DIA-49803: Purge not possible due to incompatible schema version. == Eine weitere Ursache warum nach z.b einem Upgrade ein Löschen nicht mehr funktioniert ist: adrci> set home diag/clients/user_grid/host_737992941_82 adrci> purge -age 0 DIA-49803: Purge not possible due to incompatible schema version. Als erstes darauf achten, das auch das richtige ADRCI ( das aus dem aktuellen 18'er bzw. 12'er Home ) gestartet wird! Danach folgende Node beachten! => siehe ADRCI Error DIA-49803 - Purge Does Not Work In 12.2 If ADRCI Is Used To Access An Older ADR Home (Doc ID 2341825.1) Das hat mir aber dann auch nicht weitergeholfen, bei mir hat folgendes geklappt: adrci> migrate schema Schema migrated. adrci> purge -age 0 ---- ==== Quellen ==== Web: * https://valehagayev.wordpress.com/2016/07/16/automatically-and-manual-purging-alert-log-and-trace-files-with-automatic-diagnostic-repository-command-interpreter-adrci/ * https://www.oracle.com/webfolder/technetwork/de/community/dbadmin/tipps/adrci/index.html ADRCI * https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sutil/oracle-adr-command-interpreter-adrci.html#GUID-92DD451B-C3A1-48D7-A147-3296E75572CB Support: * Automatic Diagnostic Cleanup - Auto purge (Doc ID 1196437.1) * Retention Policy for ADR (Doc ID 564269.1)