כדי להשתמש ב-Oracle Direct NFS (dNFS) עם מכשיר גיבוי או שחזור, צריך לעמוד בדרישות הבאות:
רוחב פס מספיק ברשת בין שרת מסד הנתונים לבין מכשיר הגיבוי או השחזור
משתמשים בכל התיקונים הנדרשים או המומלצים של Oracle. חברת Oracle מתחזקת רשימה של תיקונים נדרשים או מומלצים במסמכי התמיכה של Oracle.
הגדרת מסוף הניהול של ה-appliance להגנה על מסדי נתונים וירטואליים של Oracle ולטעינתם באמצעות dNFS
כדי לבצע גיבוי מבוסס dNFS, צריך להגדיר את פורמט הדיסק של מכשיר הגיבוי/השחזור (העדפת הדיסק) ל-NFS.
כדי להגדיר את פורמט הדיסק של סביבת ה-Staging (העדפת הדיסק) ל-NFS, פועלים לפי ההוראות הבאות:
עוברים אל ניהול > מארחים.
לוחצים לחיצה ימנית על המארח ובוחרים באפשרות עריכה.
בפורמט של דיסק ההכנה, בוחרים באפשרות NFS ולוחצים על שמירה.
פעולות שצריך לבצע במארח היעד כדי ש-dNFS יפעל
כדי לוודא ש-dNFS מוגדר בצורה נכונה, מבצעים את הפעולות הבאות:
כדי לוודא ש-dNFS מופעל, מחפשים את ההודעה הבאה בקובץ DB Alert.log:
Oracle instance running with ODM: Oracle Direct NFS ODM Library Version 3.01.אם dNFS לא מופעל, צריך להפעיל אותו:
חבילות של לקוח NFS צריכות להיות קיימות במארח מסד הנתונים עבור משימות הגנה, ובכל מארח Oracle שבו אתם עשויים לטעון מסד נתונים של Oracle שצולם באמצעות dNFS. לדוגמה, ב-Linux, חבילת
nfs-utilצריכה להיות קיימת במארח. כדאי לבדוק את הדברים הבאים:rpm -qa |grep nfs-util
הפעלת dNFS במארח Oracle:
cd $ORACLE_HOME/rdbms/lib make -f ins_rdbms.mk dnfs_on
מפעילים מחדש את מסדי הנתונים שפועלים ב-
ORACLE_HOME, ואז בודקים אם ההודעה הבאה מופיעה בקטע DB Alert.log כדי לוודא ש-dNFS מופעל:מופע Oracle שפועל עם ODM: Oracle Direct NFS ODM Library Version 3.0
במהלך עבודת הגיבוי, מריצים את השאילתה הבאה כדי לבדוק את השימוש ב-dNFS:
select * from gv$dnfs_servers;אפשר לראות את הנתונים הסטטיסטיים של NFS read/write עבור פעולות קלט/פלט שמתבצעות:
select inst_id, PNUM, NFS_READ, NFS_WRITE, NFS_COMMIT, NFS_MOUNT from gv$dnfs_stats where NFS_READ>0 or NFS_WRITE>0 order by inst_id, PNUM;אנחנו יכולים לראות את פרטי התהליך של ערוץ ה-dnfs.
select c.inst_id, program, pid,pname, local, path from gv$process p, gv$dnfs_channels c where p.inst_id = c.inst_id and c.pnum = p.pid;
פתרון בעיות ב-dNFS: בעיות במסד הנתונים
למשל:
יומן ההתראות
השלב הראשון בכל פעולת ניפוי באגים הוא לבדוק את יומן ההתראות לגבי הודעות שקשורות ל-dNFS. בעיה נפוצה שנצפית במסדי נתונים עם dNFS היא הגודל המוגבל של שטח אחסון זמני של שקע. Oracle מנסה להתאים את הגודל, אבל יכול להיות שהמערכת תגביל את זה. במקרה כזה, שגיאה כמו זו שמופיעה כאן נמצאת ביומן ההתראות:
Direct NFS: Failed to set socket buffer size.wtmax=[1048576]\
rtmax=[1048576], errno=-1
פריטים נוספים שכדאי לחפש ביומן ההתראות הם אם נעשה שימוש בכרטיסי הרשת הנכונים כדי לתקשר עם ה-filer. אפשר לזהות את זה לפי הודעה שדומה להודעה הבאה:
Direct NFS: channel id [0] path [192.168.56.3] to filer [192.168.56.3] via local [] is UP
קבצים של פרטי העברה של מסד נתונים
אם מתרחשות בעיות קלט/פלט, אפשר להגדיר את האירועים הבאים במסד הנתונים כדי לתעד מידע נוסף ביומן. מגדירים את האירועים האלה, מחכים שהאירוע יתרחש ואז בודקים את הקבצים כדי לעקוב אחריו.
ALTER SYSTEM SET MAX_DUMP_FILE_SIZE =UNLIMITED;
ALTER SYSTEM SET EVENTS '10298 trace name context forever, level 1'; # KSFD I/O tracing
ALTER SYSTEM SET EVENTS '19392 trace name context forever, level 8'; # kgnfs tracing
ALTER SYSTEM SET EVENTS '19394 trace name context forever, level 8'; # skgnfs tracing
ALTER SYSTEM SET EVENTS '19396 trace name context forever, level 6'; # kgodm tracing
ALTER SYSTEM SET EVENTS '19398 trace name context forever, level 128'; # mount tracing errors
מסד הנתונים לא מגיב
אם מסד נתונים שפועל ב-dNFS לא מגיב, צריך להיכנס בתור SYSDBA באמצעות sqlplus ולבצע hanganalyze או dump:
```oradebug
oradebug setmypid
oradebug unlimited
oradebug hanganalyze 3
oradebug dump systemstate 266
```
אם מסד הנתונים הוא מסד נתונים של RAC, צריך להוסיף את האפשרות -g לשתי פקודות ה-oradebug האחרונות.
תצוגות dNFS
לקוח ה-dNFS נמצא בפועל בקרנל של מסד הנתונים. לכן, קיימים כמה תצוגות v$ במסד הנתונים כדי לעקוב אחרי התקינות של dNFS ולבדוק אותה מתוך מסד הנתונים. Oracle מספקת חבילה שאפשר להשתמש בה כדי לעקוב במהירות אחרי הביצועים של dNFS. החבילה הזו נמצאת בחבילת המעקב של Oracle dNFS.
אחרי הפריסה, DBA יכול לבצע את הפעולות הבאות כדי לקבל מידע (פרמטרים: dnfs_monitor(sleep time), dnfs_itermonitor (sleep time,number of times to check), sleep time is in seconds):
SQL> set serveroutput on
SQL> set lines 200
SQL> exec dnfs_monitor(60);
Started at 01/18/2017 10:09:46 AM
Finished at 01/18/2017 10:10:46 AM
READ IOPS: 2
WRITE IOPS: 3
TOTAL IOPS: 5
READ Throughput: 0 MB/s
WRITE Throughput: 0 MB/s
TOTAL Throughput: 0 MB/s
SQL> exec dnfs_itermonitor(2,10)
Started at 01/18/2017 10:20:18 AM
TIMESTAMP READ IOPS WRITE IOPS TOTAL IOPS READ(MB/s) WRITE (MB/s) TOTAL (MB/s)
01/18/2017 10:20:20 AM 15 7 22 0 0 0
01/18/2017 10:20:22 AM 2 3 5 0 0 0
01/18/2017 10:20:24 AM 0 3 3 0 0 0
01/18/2017 10:20:26 AM 2 2 4 0 0 0
01/18/2017 10:20:28 AM 0 3 3 0 0 0
01/18/2017 10:20:30 AM 2 3 5 0 0 0
01/18/2017 10:20:32 AM 4 3 7 0 0 0
01/18/2017 10:20:34 AM 0 3 3 0 0 0
01/18/2017 10:20:36 AM 2 3 5 0 0 0
01/18/2017 10:20:38 AM 2 3 5 0 0 0
Finished at 01/18/2017 10:20:38 AM
התצוגות של V$:
V$DNFS_SERVER: מציג מידע על כל חיבורי שרת NFS (אחד לכל שרת NFS). התצוגה שימושית כדי לוודא את הקישוריות ואת הגדרות שקע ה-TCP.
V$DNFS_CHANNELS: מציג מידע על כל נתיבי הרשת שנוצרו לשרתי NFS. כל לקוח dNFS יוצר ערוץ אחד לכל תהליך לכל נתיב ברשת. אם קיימים כמה נתיבים (כמה כרטיסי רשת), לקוח ה-dNFS מבצע איזון עומסים בכל הערוצים. הנתונים משקפים את הפעילות מאז הבחירה האחרונה.
V$DNFS_FILES: הצגת קבצים שפתוחים באמצעות לקוח dNFS.
V$DNFS_STAT: מדדי ביצועים ללקוח dNFS.
| עמודה | תיאור |
|---|---|
SRVNAME
|
שם שרת NFS |
DIRNAME
|
נפח הנתונים שמיוצאים על ידי שרת NFS |
MNTPORT
|
יציאת טעינה מקומית |
NFSPORT
|
יציאה של שרת NFS |
WTMAX
|
גודל הכתיבה המקסימלי לשרת NFS |
RTMAX
|
גודל קריאה מקסימלי לשרת NFS |
| עמודה | תיאור |
|---|---|
PNUM
|
מספר התהליך של Oracle (קישור ל-PID ב-v$process) |
SVRNAME
|
השם של שרת ה-NFS |
PATH
|
נתיב ברשת לשרת |
CH_ID
|
מזהה ערוץ dNFS |
SVR_ID
|
מזהה שרת dNFS |
SENDS
|
שליחת פעולות בערוץ מאז הבחירה האחרונה. |
RECVS
|
קבלת פעולות בערוץ מאז הבחירה האחרונה. |
PINGS
|
פעולות פינג בערוץ מאז הבחירה האחרונה. |
| עמודה | תיאור |
|---|---|
FILENAME
|
שם הקובץ. |
FILESIZE
|
גודל הקובץ. |
PNUM
|
מזהה תהליך (קישור למזהה התהליך ב-v$process) |
SRV_ID
|
מזהה שרת NFS |
| עמודה | תיאור |
|---|---|
PNUM
|
מספר התהליך של Oracle (קישור ל-PID ב-v$process)
|
NFS_NULL
|
Null operations
|
NFS_GETATTR
|
קבלת פעולות של מאפיינים |
NFS_SETATTR
|
הגדרת פעולות על מאפיינים |
NFS_LOOKUP
|
פעולות חיפוש |
NFS_ACCESS
|
פעולות גישה |
NFS_READLINK
|
קריאת פעולות קישור |
NFS_READ
|
פעולות קריאה |
NFS_WRITE
|
פעולות כתיבה |
NFS_CREATE
|
יצירת פעולות |
NFS_MKDIR
|
ביצוע פעולות בספריות |
NFS_MKNOD
|
ביצוע פעולות בצומת |
NFS_SYMLINK
|
פעולות של קישורים סמליים |
NFS_REMOVE
|
הסרת פעולות |
NFS_RMDIR
|
הסרת פעולות בספריות |
NFS_RENAME
|
שינוי שמות של פעולות |
NFS_LINK
|
פעולות שקשורות לקישורים |
NFS_READDIR
|
קריאת פעולות בספרייה |
NFS_READDIRPLUS
|
קריאה של פעולות בספרייה |
NFS_FSSTAT
|
פעולה של סטטוס מערכת הקבצים |
NFS_FSINFO
|
פעולות מידע במערכת הקבצים |
NFS_PATHCONF
|
פעולות להגדרת נתיב |
NFS_COMMIT
|
ביצוע פעולות |
NFS_MOUNT
|
פעולות טעינה |
חבילת המעקב Oracle dNFS
CREATE OR REPLACE PROCEDURE dnfs_monitor
(sleepSecs IN NUMBER)
IS
startTime DATE;
startReadIOPS NUMBER;
startWriteIOPS NUMBER;
startReadBytes NUMBER;
startWriteBytes NUMBER;
endTime DATE;
endReadIOPS NUMBER;
endWriteIOPS NUMBER;
endReadBytes NUMBER;
endWriteBytes NUMBER;
readThr NUMBER;
writeThr NUMBER;
readIOPS NUMBER;
writeIOPS NUMBER;
elapsedTime NUMBER;
BEGIN
SELECT sysdate, SUM(stats.nfs_readbytes), SUM(stats.nfs_writebytes),
SUM(stats.nfs_read), SUM(stats.nfs_write)
INTO startTime, startReadBytes, startWriteBytes, startReadIOPS, startWriteIOPS
FROM dual, v$dnfs_stats stats;
DBMS_OUTPUT.PUT_LINE('Started at ' || TO_CHAR(startTime,'MM/DD/YYYY HH:MI:SS AM'));
DBMS_LOCK.SLEEP(sleepSecs);
SELECT sysdate, SUM(stats.nfs_readbytes), SUM(stats.nfs_writebytes), SUM(stats.nfs_read), SUM(stats.nfs_write)
INTO endTime, endReadBytes, endWriteBytes, endReadIOPS, endWriteIOPS
FROM dual, v$dnfs_stats stats;
DBMS_OUTPUT.PUT_LINE('Finished at ' || to_char(endTime,'MM/DD/YYYY HH:MI:SS AM'));
elapsedTime := (endTime - startTime) * 86400;
readThr := (endReadBytes - startReadBytes)/(1024 * 1024 * elapsedTime);
writeThr := (endWriteBytes - startWriteBytes)/(1024 * 1024 * elapsedTime);
readIOPS := (endReadIOPS - startReadIOPS)/elapsedTime;
writeIOPS := (endWriteIOPS - startWriteIOPS)/elapsedTime;
DBMS_OUTPUT.PUT_LINE('READ IOPS: ' || LPAD(TO_CHAR(readIOPS, '999999999'), 10, ' '));
DBMS_OUTPUT.PUT_LINE('WRITE IOPS: ' || LPAD(TO_CHAR(writeIOPS,
'999999999'), 10, ' '));
DBMS_OUTPUT.PUT_LINE('TOTAL IOPS: ' || LPAD(TO_CHAR(readIOPS + writeIOPS, '999999999'), 10, ' '));
DBMS_OUTPUT.PUT_LINE('READ Throughput: ' || LPAD(TO_CHAR(readThr, '999999999'), 10, ' ') || ' MB/s');
DBMS_OUTPUT.PUT_LINE('WRITE Throughput: ' || LPAD(TO_CHAR(writeThr,
'999999999'), 10, ' ') || ' MB/s');
DBMS_OUTPUT.PUT_LINE('TOTAL Throughput: ' || LPAD(TO_CHAR(readThr + writeThr, '999999999'), 10, ' ') || ' MB/s');
END;
/
CREATE OR REPLACE PROCEDURE dnfs_itermonitor
(sleepSecs IN NUMBER,
iter IN NUMBER)
IS
startTime DATE;
startReadIOPS NUMBER;
startWriteIOPS NUMBER;
startReadBytes NUMBER;
startWriteBytes NUMBER;
endTime DATE;
endReadIOPS NUMBER;
endWriteIOPS NUMBER;
endReadBytes NUMBER;
endWriteBytes NUMBER;
readThr NUMBER;
writeThr NUMBER;
readIOPS NUMBER;
writeIOPS NUMBER;
i NUMBER;
elapsedTime NUMBER;
BEGIN
DBMS_OUTPUT.PUT_LINE('Started at ' || TO_CHAR(SYSDATE, 'MM/DD/YYYY HH:MI:SS AM'));
DBMS_OUTPUT.PUT_LINE(
LPAD('TIMESTAMP', 15, ' ')||
LPAD('READ IOPS', 33, ' ')||
LPAD('WRITE IOPS', 15, ' ')||
LPAD('TOTAL IOPS', 15, ' ')||
LPAD('READ (MB/s)', 15, ' ')||
LPAD('WRITE (MB/s)', 15, ' ')||
LPAD('TOTAL (MB/s)', 15, ' '));
FOR i IN 1..iter
LOOP
SELECT sysdate, SUM(stats.nfs_readbytes), SUM(stats.nfs_writebytes), SUM(stats.nfs_read), SUM(stats.nfs_write)
INTO startTime, startReadBytes, startWriteBytes, startReadIOPS, startWriteIOPS
FROM dual, v$dnfs_stats stats;
DBMS_LOCK.SLEEP(sleepSecs);
SELECT sysdate, SUM(stats.nfs_readbytes), SUM(stats.nfs_writebytes), SUM(stats.nfs_read), SUM(stats.nfs_write)
INTO endTime, endReadBytes, endWriteBytes, endReadIOPS, endWriteIOPS
FROM dual, v$dnfs_stats stats;
elapsedTime := (endTime - startTime) * 86400;
readThr := (endReadBytes-startReadBytes)/(1024 * 1024 * elapsedTime);
writeThr := (endWriteBytes-startWriteBytes)/(1024 * 1024 * elapsedTime);
readIOPS := (endReadIOPS - startReadIOPS)/elapsedTime;
writeIOPS := (endWriteIOPS - startWriteIOPS)/elapsedTime;
DBMS_OUTPUT.PUT_LINE(
TO_CHAR(endTime, 'MM/DD/YYYY HH:MI:SS AM')||
LPAD(TO_CHAR(readIOPS, '999999999'), 15, '') ||
LPAD(TO_CHAR(writeIOPS, '999999999'), 15,' ') ||
LPAD(TO_CHAR(readIOPS + writeIOPS, '999999999'),15, ' ') ||
LPAD(TO_CHAR(readThr, '999999999'), 15, '') ||LPAD(TO_CHAR(writeThr, '999999999'), 15, '
') ||
LPAD(TO_CHAR(readThr + writeThr, '999999999'), 15, ' '));
END LOOP;
DBMS_OUTPUT.PUT_LINE('Finished at ' || to_char(endTime, 'MM/DD/YYYY HH:MI:SS AM'));
END;
המדריך למנהלי מסדי נתונים של Oracle
- Backup and DR עבור מסדי נתונים של Oracle
- דרישות מוקדמות להגנה על מסד נתונים של Oracle
- תיקונים ובעיות מוכרות ב-Oracle
- הכנת מסדי נתונים של Oracle להגנה
- גילוי והגנה על מסד נתונים של Oracle
- פרטים והגדרות למסדי נתונים של Oracle
- שימוש ב-dNFS עם Backup and DR
- הגנה על מסד נתונים של Oracle שזוהה
- איך מצמידים מסד נתונים של Oracle כהצמדה רגילה
- יצירת עותק וירטואלי מיידי של מסד נתונים של Oracle
- שחזור מסד נתונים של Oracle
- שחזור מיידי של מסד נתונים של Oracle באמצעות Mount and Migrate
- הקצאת סביבה עם תהליך עבודה של Backup and DR