由于文件組 ‘DEFAULT’ 中的磁盤空間不足,無法為數(shù)據(jù)庫 ‘TEMPDB’ 分配新頁

字號(hào):


    今天接到一個(gè)朋友的問題,sql server報(bào)“由于文件組 ‘DEFAULT’ 中的磁盤空間不足,無法為數(shù)據(jù)庫 ‘TEMPDB’ 分配新頁”,按照錯(cuò)誤提示應(yīng)該是tempdb空間不足,讓其查看tempdb對(duì)應(yīng)數(shù)據(jù)庫文件大小為不到4g,查看其對(duì)應(yīng)文件為自增長,硬盤空間還有40g多點(diǎn),那應(yīng)該沒有問題。后來她說該文件所處位置的盤是fat32的,那問題確定是fat32最大支持文件大小是4g。解決辦法:
    1、讓tempdb中的文件恢復(fù)默認(rèn)值,設(shè)置其最大值
    1)重啟sql server服務(wù),tempdb一般會(huì)自動(dòng)變?yōu)槌跏蓟笮?BR>    2)如果1)失敗,使用下面語句
    dbcc shrinkfile (tempdev, 10)
    dbcc shrinkfile (templog, 10)
    2)然后設(shè)置tempdev和templog的最大大小為4000m
    2、添加數(shù)據(jù)文件和日志文件,并設(shè)置其最大值為4000m
    3、修改程序,從根源上解決問題
    分析產(chǎn)生該問題原因
    詢問朋友后,原來是她對(duì)一個(gè)6kw的表和1kw的表進(jìn)行關(guān)聯(lián),然后取得需要的數(shù)據(jù)插入到另一張表中,因?yàn)樯婕暗臄?shù)據(jù)量非常大,所有導(dǎo)致tempdb數(shù)據(jù)庫飛速增大,超過系統(tǒng)文件大小限制。導(dǎo)致文章開始的錯(cuò)誤,光添加文件,對(duì)于這么大數(shù)據(jù)量的程序來說還是不能解決問題。應(yīng)該在程序上去優(yōu)化,而不是靠添加tempdb中文件的大小和數(shù)量來解決問題。
    添加程序的提交次數(shù),而不是所有數(shù)據(jù)一次提交,放在一個(gè)事物中。
    我根據(jù)程序需求模擬的寫了兩種處理過程的方法
    模擬環(huán)境:
    --創(chuàng)建模擬表
    SELECT id,name INTO t_1 FROM sys.sysobjects;
    SELECT object_id id,name INTO t_2 FROM sys.columns;
    --創(chuàng)建跟蹤表
    CREATE TABLE t_s (id int DEFAULT 0,date datetime DEFAULT getdate());
    INSERT INTO t_s VALUES(0,getdate());
    --創(chuàng)建需要插入數(shù)據(jù)表
    SELECT t1.name n1,
    t2.name n2,
    t1.id
    INTO test_1
    FROM t_1 t1,
    t_2 t2
    WHERE t1.id = t2.id
    AND 1=2;
    方法一:
    特點(diǎn):1、優(yōu)點(diǎn)執(zhí)行效率比較高,無需排序和插入跟蹤表
    2、缺點(diǎn):不能查看程序執(zhí)行進(jìn)度,如果異常終止,必須重新執(zhí)行
    create PROCEDURE [dbo].[INSERT_d_1]
    AS
    DECLARE @name1 varchar(4000)
    DECLARE @name2 varchar(4000)
    DECLARE @id int
    DECLARE c1 CURSOR
    FOR
    SELECT t1.name,
    t2.name,
    t1.id
    FROM t_1 t1,
    t_2 t2
    WHERE t1.id = t2.id
    ORDER BY
    t1.id
    open c1
    fetch next from c1 into @name1,@name2,@id
    WHILE @@fetch_status=0
    BEGIN
    INSERT INTO test_1 VALUES(@name1,@name2,@id)
    FETCH next FROM c1 INTO @name1,@name2,@id
    END
    CLOSE c1
    DEALLOCATE c1
    方法二:
    特點(diǎn):1、可以跟蹤程序的執(zhí)行進(jìn)度查詢t_s表,如果異常終止可以寫其他程序繼續(xù)
    2、程序使用二重游標(biāo),執(zhí)行效率比較低
    create PROCEDURE [dbo].[INSERT_d_2]
    AS
    DECLARE @name1 varchar(4000)
    DECLARE @name2 varchar(4000)
    DECLARE @id int
    DECLARE c1 CURSOR
    FOR
    SELECT t1.name,
    t1.id
    FROM t_1 t1
    ORDER BY t1.id
    open c1
    fetch next from c1 into @name1,@id
    WHILE @@fetch_status=0
    BEGIN
    --二重循環(huán)
    DECLARE c2 CURSOR FOR
    SELECT t2.name FROM t_2 t2 WHERE t2.id=@id
    OPEN c2
    FETCH next FROM c2 INTO @name2
    WHILE @@FETCH_STATUS=0
    BEGIN
    INSERT INTO test_1 VALUES(@name1,@name2,@id)
    UPDATE t_s SET id=@id,date=getdate()
    FETCH next FROM c2 INTO @name2
    END
    CLOSE c2
    DEALLOCATE c2
    FETCH next FROM c1 INTO @name1,@id
    END
    CLOSE c1
    DEALLOCATE c1