我先將restic 所備份最新版nextcloud備份的snapshot掛載起來,接著停用目前的資料庫(mariadb 10.3.2 多個容器共用);再將nextcloud的相關volume、資料庫還原,結果失敗,失敗原因不明,docker看log也看不出來,web登入出現「Nextcloud the server was unable to complete your request」錯誤,真真急死人;後來爬文,歸納問題可能有三種:目錄權限沒設定好、資料庫問題與ldap無法連線。
some pack files are missing from the repository, getting their blobs from the repository index: [c3622b51e9c118521af211cd3a98f580f5902824b6b665e62d61061acedbe71d]
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 21600
undo_tablespace string UNDOTBS1
SQL> ALTER SYSTEM SET UNDO_RETENTION = 43200;
SQL>
System altered.
SQL>
# 新增undo tablespace
create undo tablespace UNDOTBS2 datafile '/.../oradata/undotbs02.dbf' size 30000M autoextend on next 100m maxsize unlimited;
#生效
alter system set undo_tablespace = UNDOTBS2 scope=both;
#查看狀態
select tablespace_name, status, count(*) from dba_rollback_segs group by tablespace_name, status;
select status,segment_name from dba_rollback_segs where status not in ('OFFLINE') and tablespace_name='UNDOTBS1';
select tablespace_name, status, count(*) from dba_rollback_segs group by tablespace_name, status;
#確認舊的已是offline , 就可以刪掉舊的
Drop tablespace UNDOTBS1 including contents and datafiles;
#再次查看是否已變成新的undo tablespace
show parameter undo
select tablespace_name tablespace, status, sum(bytes)/1024/1024 sum_in_mb, count(*) counts
from dba_undo_extents
group by tablespace_name, status order by 1,2;
# 以下紅色部分請改為有問題資料表與欄位名稱, 若沒有出現錯誤, 就換下一個欄位(fieldname)試試看
SET TIMING ON
DECLARE
ERROR_1578 EXCEPTION;
ERROR_1555 EXCEPTION;
ERROR_22922 EXCEPTION;
PRAGMA EXCEPTION_INIT(ERROR_1578, -1578);
PRAGMA EXCEPTION_INIT(ERROR_1555, -1555);
PRAGMA EXCEPTION_INIT(ERROR_22922, -22922);
N NUMBER;
BEGIN
FOR ROW IN (SELECT ROWID, fieldname FROM user.table)
LOOP
BEGIN
N:=DBMS_LOB.INSTR(ROW.fieldname, HEXTORAW('889911'));
EXCEPTION
WHEN ERROR_1578 THEN
INSERT INTO CORRUPTED_ROWS VALUES (ROW.ROWID, 1578);
COMMIT;
WHEN ERROR_1555 THEN
INSERT INTO CORRUPTED_ROWS VALUES (ROW.ROWID, 1555);
COMMIT;
WHEN ERROR_22922 THEN
INSERT INTO CORRUPTED_ROWS VALUES (ROW.ROWID, 22922);
COMMIT;
END;
END LOOP;
END;
/
接下來查詢是否真有問題資料
SELECT * FROM CORRUPTED_ROWS;
#執行以下這行指令應該要出錯
SELECT fieldname FROM user.table WHERE ROWID IN (SELECT CORRUPTED_ROWID FROM CORRUPTED_ROWS);
清空有問題的資料欄位
#若欄位型態是clob就用empty_clob(), 若為blob,就改成empty_blob(), 有幾個欄位出問題就清空幾個
update xxx.table set fieldname = empty_clob()where ROWID IN (SELECT CORRUPTED_ROWID FROM CORRUPTED_ROWS);
若不敢清空, 可以跳過有問題的資料備份
exp system@yourinstance BUFFER=81920 file=/tmp/backup.dmp tables=user.table QUERY=\"WHERE rowid NOT IN \(SELECT CORRUPTED_ROWID FROM CORRUPTED_ROWS\)\"