前言:本文主要分爲兩部分。第一部分是在工做中遇到的SQL0294N報錯以及相關的分析、處理過程。第二部分是在我的虛擬機上對db2untag指令的試驗。node
0背景:預投產環境,已建好ord數據庫。可是因爲應用側作規劃時字符集規劃錯誤,數據庫字符集在建立數據庫時已經指定,建立完成後沒法修改,因此只能刪除並重建數據庫ord。重建數據庫表空間時提示容器重用,報SQL0294N錯誤。sql
1斷開全部應用鏈接後,刪除ORD數據庫,成功數據庫
db2 force applications all服務器 db2 deactivate db ordapp db2 drop db ordide DB20000I The DROP DATABASE command completed successfully.fetch |
2新建數據庫ORD,成功ui
db2 "create database ORD automatic storage yes on /db2node02 dbpath on /db2node02 using codeset UTF-8 territory cn restrictive"spa |
3配置完參數,成功rest
db2 activate database ord db2 connect to ord db2 "update db cfg for ORD using NEWLOGPATH /db2log02" |
4新建緩衝池,成功
db2 "CREATE BUFFERPOOL ord_BP8K IMMEDIATE SIZE 40000 PAGESIZE 8K" |
5新建表空間,報錯SQL0294N,容器已經在使用中。
db2 "create tablespace ts_ord_dat01 pagesize 8k managed by database using (device '/dev/rts_ord_01_1' 50g,device '/dev/rts_ord_01_2' 50g,device '/dev/rts_ord_01_3' 50g) bufferpool ord_BP8K "
SQL0294N The container is already in use. |
出現這個報錯時我很納悶,想固然地覺得數據庫已經刪除成功了,表空間的容器就不會再存在了。
納悶概括悶,有問題仍是要解決。個人第一反應是刪除容器重建容器,建完容器以後再建表空間。
rmlv ts_ord_01_1 rmlv ts_ord_01_2 rmlv ts_ord_01_3
mklv -y ts_ord_01_1 ord1vg 200 mklv -y ts_ord_01_2 ord1vg 200 mklv -y ts_ord_01_3 ord1vg 200
chown db2inst2:db2grp2 /dev/rts_ord_01_1 chown db2inst2:db2grp2 /dev/rts_ord_01_2 chown db2inst2:db2grp2 /dev/rts_ord_01_3
db2 "create tablespace ts_ord_dat01 pagesize 8k managed by database using (device '/dev/rts_ord_01_1' 50g,device '/dev/rts_ord_01_2' 50g,device '/dev/rts_ord_01_3' 50g) bufferpool ord_BP8K "
SQL0294N The container is already in use. |
作到這一步依然報錯SQL0294N,我一時間沒有頭緒,不知道緣由出在哪裏。第一次建表空間報錯應該是由於沒有執行刪容器的指令,第二次建表空間,容器已經刪除重建了,依然報錯。對於DB2的報錯,最直接的辦法就是查詢官方文檔尋找答案。
6查閱官方文檔,關於SQL0294N報錯:
SQL0294N 容器已在使用中。 說明 沒法共享表空間容器。致使此錯誤的可能緣由包括下列各項。 · CREATE TABLESPACE 或 ALTER TABLESPACE 語句包括了另外一個表空間已在使用的容器。 · CREATE TABLESPACE 或 ALTER TABLESPACE 語句包括了來自這樣的表空間的容器:它已被刪除但還未落實刪除語句。 · 用來添加數據庫分區的 ALTER DATABASE PARTITION 語句使用了在同一物理數據庫分區上的 LIKE 數據庫分區的容器。所以這些容器已在使用中。 · CREATE TABLESPACE 或 ALTER TABLESPACE 語句正在嘗試在單個物理數據庫分區的多個邏輯數據庫分區上使用同一容器。不能將同一容器用於同一物理數據庫分區上的多個數據庫分區。 · ADD DATABASE PARTITION 命令或 API 使用了來自同一物理數據庫分區上 LIKE 數據庫分區的系統臨時表空間的容器。所以這些容器已在使用中。 · CREATE TABLESPACE 語句、ALTER TABLESPACE 語句或 CREATE DATABASE 命令包括了再也不存在、但未正確刪除的另外一個數據庫中的 DMS 容器。該容器實際上未在使用中,可是它被標記爲正在使用。所以,在取消其標記以前,DB2 數據服務器將不容許對其進行使用。然而,當取消其標記時,驗證該容器是否未在被同一數據庫或另外一個數據庫使用是很重要的。取消容器的標記時,若是它正在使用中,那麼所涉及的數據庫將損壞。 · REORG 嘗試自動選擇要使用的 DMS 臨時表空間,雖然存在一個具備合適頁大小的 DMS 臨時表空間,但它當前正被另外一 REORG 命令使用。 · REDISTRIBUTE 命令的 ADD DBPARTITIONNUM 選項(此選項用於添加數據庫分區)將根據編號最小的數據庫分區上的表空間的表空間容器名,實如今新添加的數據庫分區上建立表空間容器名。若是這些容器名指定了絕對路徑,而且新的數據庫分區與使用相同容器名的數據庫分區在同一物理設備上,那麼已經在使用新分區的容器。 · RESTORE DATABASE 命令在數據庫中找到了再也不存在、可是未正確刪除的容器。 · 爲傳輸操做建立了臨時登臺數據庫,而後嘗試了在該臨時登臺數據庫仍存在的狀況下在目標數據庫上建立表空間。 用戶響應 確保容器惟一。 · 對於 CREATE 或 ALTER TABLESPACE 語句,對錶空間指定不一樣的容器。 · 對於包括來自已刪除表空間的容器的 CREATE 或 ALTER TABLESPACE 語句,落實刪除語句以後再次嘗試,或指定不一樣的容器。 · 對於 ALTER DATABASE PARTITION 語句,使用 WITHOUT TABLESPACES 子句從新發出該語句,而後使用 ALTER TABLESPACE 語句爲新的數據庫分區建立惟一的容器。 · 對於環境包括一個物理數據庫分區上多個邏輯數據庫分區的 CREATE 或 ALTER TABLESPACE 語句,確保未對這樣的邏輯數據庫分區指定相同的容器。 · 對於 ADD DATABASE PARTITION 命令或 API,使用 WITHOUT TABLESPACES 子句從新發出該語句,而後使用 ALTER TABLESPACE 語句在新數據庫分區上爲系統臨時表空間建立惟一的容器。 · 若是嘗試使用一個屬於再也不存在但未正確刪除的數據庫的 DMS 容器,那麼可使用 db2untag 實用程序來從容器除去 DB2 容器標記。當除去了此標記時,DB2 就認爲該容器是可用的,且能夠在 CREATE TABLESPACE 語句、ALTER TABLESPACE 語句或 CREATE DATABASE 命令中使用該容器。 注意:使用 db2untag 時要特別當心。若是您對數據庫仍在使用的容器發出 db2untag 命令,那麼最初使用該容器的數據庫以及如今正在使用該容器的數據庫都將毀壞。 · 對於 REORG,一旦使用所需表空間的初始 REORG 完成,請從新提交該命令,或者提供另外一具備合適頁大小的臨時表空間供使用。 · 對於 REDISTRIBUTE 命令,選擇不使用 ADD DBPARTITIONNUM 選項,而是改成執行如下操做:在發出 REDISTRIBUTE 命令以前,發出附帶了 WITHOUT TABLESPACES 子句的 ALTER DATABASE PARTITION GROUP 語句,而後使用 ALTER TABLESPACE 語句爲新數據庫分區建立惟一的容器。 · 對於 RESTORE DATABASE 命令(容器屬於一個再也不存在、可是未正確刪除的數據庫),請除去此容器。 注意:在除去容器以前,確保該容器沒有正在被另外一個數據庫使用。 · 若是爲傳輸操做建立了臨時登臺數據庫,那麼在再也不須要改臨時登臺數據庫以後除去該登臺數據庫,而後在目標上嘗試因存在該登臺數據庫而被阻止的操做。 sqlcode:-294 sqlstate:42730 |
7解決方法:
根據官方文檔和實際狀況判斷,本例應該屬於這種狀況:「若是嘗試使用一個屬於再也不存在但未正確刪除的數據庫的 DMS 容器,那麼可使用 db2untag 實用程序來從容器除去 DB2 容器標記。當除去了此標記時,DB2 就認爲該容器是可用的,且能夠在 CREATE TABLESPACE 語句、ALTER TABLESPACE 語句或 CREATE DATABASE 命令中使用該容器。」
注意:使用 db2untag 時要特別當心。若是您對數據庫仍在使用的容器發出 db2untag 命令,那麼最初使用該容器的數據庫以及如今正在使用該容器的數據庫都將毀壞。
8具體操做:
對容器進行db2untag -f操做,類比建立lv的語句。
mklv -y ts_ord_01_1 ord1vg 200 mklv -y ts_ord_01_2 ord1vg 200 mklv -y ts_ord_01_3 ord1vg 200 |
則對應的db2untag語句爲:
db2untag -f ts_ord_01_1 db2untag -f ts_ord_01_2 db2untag -f ts_ord_01_3 |
9對容器執行db2untag後,再進行建立表空間語句,建立成功。
db2 "create tablespace ts_ord_dat01 pagesize 8k managed by database using (device '/dev/rts_ord_01_1' 50g,device '/dev/rts_ord_01_2' 50g,device '/dev/rts_ord_01_3' 50g) bufferpool ord_BP8K " |
10以上是在預投產環境的操做記錄。總結此次報錯,重建數據庫時,咱們須要在刪除舊數據庫前,先執行如下指令,把表空間容器正確刪除,而後才刪庫。
db2 "alter tablespace ts_ord_dat01 drop (device '/dev/rts_ord_01_1' ,device '/dev/rts_ord_01_2' ,device '/dev/rts_ord_01_3' )「 |
在虛擬機上試驗db2untag
0查閱官方文檔時,我留意到文檔裏的注意事項:使用 db2untag 時要特別當心。若是您對數據庫仍在使用的容器發出 db2untag 命令,那麼最初使用該容器的數據庫以及如今正在使用該容器的數據庫都將毀壞。因而想虛擬機上搞破壞,嘗試db2untag正常容器的危害。
1查看錶空間:
[db2inst1@localhost ~]$ db2pd -d sample -tab
Database Member 0 -- Database SAMPLE -- Active -- Up 0 days 00:15:10 -- Date 2017-02-28 14:41:47
Tablespace Configuration: Address Id Type Content PageSz ExtentSz Auto Prefetch BufID BufIDDisk FSC NumCntrs MaxStripe LastConsecPg Name 0x00007F784F825CC0 0 DMS Regular 8192 4 Yes 4 1 1 Off 1 0 3 SYSCATSPACE (省略無關內容) 0x00007F784F850860 5 DMS Large 8192 32 Yes 32 1 1 Off 1 0 31 IBMDB2SAMPLEXML 0x00007F784F8597A0 6 DMS Large 8192 32 Yes 32 2 2 Off 1 0 31 TS_SAMPL
Tablespace Statistics: Address Id TotalPgs UsablePgs UsedPgs PndFreePgs FreePgs HWM Max HWM State MinRecTime NQuiescers PathsDropped TrackmodState 0x00007F784F825CC0 0 16384 16380 16240 0 140 16240 16240 0x00000000 0 0 No n/a (省略無關內容) 0x00007F784F850860 5 4096 4064 1440 0 2624 1440 1440 0x00000000 0 0 No n/a 0x00007F784F8597A0 6 5000 4960 96 0 4864 96 96 0x00000000 0 0 No n/a
Tablespace Autoresize Statistics: Address Id AS AR InitSize IncSize IIP MaxSize LastResize LRF 0x00007F784F825CC0 0 Yes Yes 33554432 -1 No None None No (省略無關內容) 0x00007F784F850860 5 Yes Yes 33554432 -1 No None None No 0x00007F784F8597A0 6 No No 0 0 No 0 None No
Tablespace Storage Statistics: Address Id DataTag Rebalance SGID SourceSGID 0x00007F784F825CC0 0 0 No 0 - (省略無關內容) 0x00007F784F850860 5 -1 No 0 - 0x00007F784F8597A0 6 0 No - -
Containers: Address TspId ContainNum Type TotalPgs UseablePgs PathID StripeSet Container 0x00007F784CFFE480 0 0 File 16384 16380 0 0 /home/db2inst1/db2inst1/NODE0000/SAMPLE/T0000000/C0000000.CAT (省略無關內容) 0x00007F784F859560 5 0 File 4096 4064 0 0 /home/db2inst1/db2inst1/NODE0000/SAMPLE/T0000005/C0000000.LRG 0x00007F784F8624A0 6 0 File 5000 4960 - 0 /home/db2inst1/ts_sampl/sampl_container
|
DB2中,每一個表空間能夠有多個容器,容器能夠是文件、路徑、裸設備,一個容器只能屬於一個表空間。
2對正常容器執行db2untag
這裏對ID爲5的容器「下手」:
[db2inst1@localhost ~]$ db2untag -f /home/db2inst1/db2inst1/NODE0000/SAMPLE/T0000005/C0000000.LRG
db2untag: A service tool to remove the DB2 tag on a tablespace container.
The tag is used to prevent DB2 from reusing a container in more than one tablespace. If a tablespace/database is destroyed thru unnatural means, then the tag can be left behind preventing future DB2 use of the resource.
WARNING: This tool should only be used by informed sysadmins.
User will not be prompted. Using file </home/db2inst1/db2inst1/NODE0000/SAMPLE/T0000005/C0000000.LRG>
version = 214 db seed = 0 tbspSeed = 5 contID = 0 created = 1 used = 1 poolLSN = 000000000003C62E CSum = 276C6861
Instance = db2inst1 Database = SAMPLE
Container tag has been removed successfully. |
3去掉正常容器的標記後,查看錶空間狀態:
[db2inst1@localhost ~]$ db2 list tablespaces show detail |grep -i stat State = 0x0000 State = 0x0000 State = 0x0000 State = 0x0000 State = 0x0000 State = 0x4000 [db2inst1@localhost ~]$ db2tbst 4000 State = Offline and not accessible [db2inst1@localhost ~]$ db2 list tablespaces show detail
Tablespaces for Current Database Tablespace ID = 5 Name = IBMDB2SAMPLEXML Type = Database managed space Contents = All permanent data. Large table space. State = 0x4000 Detailed explanation: Offline |
該表空間處於Offline狀態:若是表空間的一個或多個容器存在問題,好比被重命名、移動、修改或者損壞時,表空間就處於該狀態。當修復容器後,能夠重啓數據庫來消除該異常狀態。或者執行ALTER TABLESPACE ... SWITCH ONLINE來消除該狀態。
4嘗試使其處於online狀態,可是沒有成功,沒法進入該表空間:
[db2inst1@localhost ~]$ db2 "alter tablespace IBMDB2SAMPLEXML switch online" DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command. During SQL processing it returned: SQL0293N Error accessing a table space container. SQLSTATE=57048 |
5因爲沒法進入該表空間,因此也沒法訪問該表空間上的表:
[db2inst1@localhost ~]$ db2 "select * from product"
PID NAME PRICE PROMOPRICE PROMOSTART PROMOEND DESCRIPTION ---------- ------ -------- -------------- ---------- ---------- -------------- SQL0290N Table space access is not allowed. SQLSTATE=55 |
6對於不在該表空間上的表能夠正常訪問:
[db2inst1@localhost ~]$ db2 "select * from employee fetch first 5 rows only"
EMPNO FIRSTNME MIDINIT LASTNAME WORKDEPT PHONENO HIREDATE JOB EDLEVEL SEX BIRTHDATE SALARY BONUS COMM ------ ------------ ------- --------------- -------- ------- ---------- -------- ------- --- ---------- ----------- ----------- ----------- 000010 CHRISTINE I HAAS A00 3978 1995-01-01 PRES 18 F 1963-08-24 152750.00 1000.00 4220.00 000020 MICHAEL L THOMPSON B01 3476 2003-10-10 MANAGER 18 M 1978-02-02 94250.00 800.00 3300.00 000030 SALLY A KWAN C01 4738 2005-04-05 MANAGER 20 F 1971-05-11 98250.00 800.00 3060.00 000050 JOHN B GEYER E01 6789 1979-08-17 MANAGER 16 M 1955-09-15 80175.00 800.00 3214.00 000060 IRVING F STERN D11 6423 2003-09-14 MANAGER 16 M 1975-07-07 72250.00 500.00 2580.00
5 record(s) selected. |
試驗事後,加深了官方文檔中關於db2untag危害的理解。使用 db2untag 時要特別當心。若是您對數據庫仍在使用的容器發出 db2untag 命令,那麼最初使用該容器的數據庫以及如今正在使用該容器的數據庫都將毀壞。
同時此次試驗又留下了一個問題:如何恢復被誤取消標記表空間容器?暫時沒有找到辦法,這個問題須要繼續深刻研究。