為什么我得到“數據庫'tempdb的日志文件'已滿”

[英]Why do I get “The log file for database 'tempdb' is full”


Let we have a table of payments having 35 columns with a primary key (autoinc bigint) and 3 non-clustered, non-unique indeces (each on one int column).

讓我們有一個支付表,其中35列包含主鍵(autoinc bigint)和3個非聚集,非唯一的indeces(每個在一個int列上)。

Among the table's columns we have two datetime fields:

在表的列中,我們有兩個datetime字段:

  1. payment_date datetime NOT NULL

    payment_date datetime NOT NULL

  2. edit_date datetime NULL

    edit_date datetime NULL

The table has about 1 200 000 rows. Only ~1000 of rows have edit_date column = null. 9000 of rows have edit_date not null and not equal to payment_date Others have edit_date=payment_date

該表有大約1 200 000行。只有~1000行有edit_date column = null。 9000行的edit_date不為null且不等於payment_date其他行有edit_date = payment_date

When we run the following query 1:

當我們運行以下查詢1時:

select top 1 *
from payments
where edit_date is not null and (payment_date=edit_date or payment_date<>edit_date)
order by payment_date desc

enter image description here

server needs a couple of seconds to do it. But if we run query 2:

服務器需要幾秒鍾才能完成。但是如果我們運行查詢2:

select top 1 *
from payments
where edit_date is not null
order by payment_date desc

enter image description here

the execution ends up with The log file for database 'tempdb' is full. Back up the transaction log for the database to free up some log space.

執行結束於數據庫'tempdb'的日志文件已滿。備份數據庫的事務日志以釋放一些日志空間。

If we replace * with some certain column, see query 3

如果我們用某些列替換*,請參閱查詢3

select top 1 payment_date
from payments
where edit_date is not null
order by payment_date desc

enter image description here

it also finishes in a couple of seconds.

它也會在幾秒鍾內完成。

Where is the magic?

魔術在哪里?

EDIT I've changed query 1 so that it operates over exactly the same number of rows as the 2nd query. And still it returns in a second, while query 2 fills tempdb.

編輯我已經更改了查詢1,以便它在與第二個查詢完全相同的行數上運行。並且它仍然在一秒鍾內返回,而查詢2填充tempdb。

ANSWER I followed the advice to add an index, did this for both date fields - everything started working quick, as expected. Though, the question was - why in this exact situation sql server behave differently on similar queries (query 1 vs query 2); I wanted to understand the logic of the server optimization. I would agree if both queries did used tempdb similarly, but they didn't....

答案我按照建議添加索引,在兩個日期字段中都這樣做 - 一切都按預期開始快速運行。雖然,問題是 - 為什么在這種情況下,sql server在類似的查詢上表現不同(查詢1與查詢2);我想了解服務器優化的邏輯。我同意,如果兩個查詢都使用了類似的tempdb,但他們沒有....

In the end I mark as the answer the first one, where I saw the must-be symptoms of my problem and the first, as well, thoughts on how to avoid this (i.e. indeces)

最后我標記為第一個答案,在那里我看到了我的問題的必然症狀,第一個,以及關於如何避免這種情況的想法(即凹痕)

2 个解决方案

#1


5  

This is happening cause certain steps in an execution plan can trigger writes to tempdb in particular certain sorts and joins involving lots of data.

發生這種情況會導致執行計划中的某些步驟觸發對tempdb的寫入,特別是涉及大量數據的某些排序和連接。

Since you are sorting a table with a boat load of columns, SQL decides it would be crazy to perform the sort alone in temp db without the associated data. If it did that it would need to do a gazzilion inefficient bookmark lookups on the underlying table.

由於您正在使用列加載列對表進行排序,因此SQL決定在沒有關聯數據的情況下在temp db中單獨執行排序會很瘋狂。如果它這樣做,它將需要在基礎表上進行一個低效的書簽查找。

Follow these rules:

遵循以下規則:

  1. Try to select only the data you need
  2. 嘗試僅選擇所需的數據
  3. Size tempdb appropriately, if you need to do crazy queries that sort a gazzilion rows, you better have an appropriately sized tempdb
  4. 適當地調整tempdb的大小,如果你需要做一個對gazzilion行進行排序的瘋狂查詢,你最好有一個適當大小的tempdb

#2


4  

Usually, tempdb fills up when you are low on disk space, or when you have set an unreasonably low maximum size for database growth. Many people think that tempdb is only used for #temp tables. When in fact, you can easily fill up tempdb without ever creating a single temp table. Some other scenarios that can cause tempdb to fill up:

通常,當磁盤空間不足時,或者為數據庫增長設置了不合理的低最大大小時,tempdb會填滿。許多人認為tempdb僅用於#temp表。實際上,您可以輕松填充tempdb而無需創建單個臨時表。其他一些可能導致tempdb填滿的場景:

  • any sorting that requires more memory than has been allocated to SQL Server will be forced to do its work in tempdb;
  • 任何需要比分配給SQL Server更多內存的排序將被強制在tempdb中完成它的工作;
  • if the sorting requires more space than you have allocated to tempdb, one of the above errors will occur;
  • 如果排序需要的空間比分配給tempdb的空間多,則會出現上述錯誤之一;
  • DBCC CheckDB('any database') will perform its work in tempdb -- on larger databases, this can consume quite a bit of space;
  • DBCC CheckDB('任何數據庫')將在tempdb中執行其工作 - 在較大的數據庫上,這可能會消耗相當多的空間;
  • DBCC DBREINDEX or similar DBCC commands with 'Sort in tempdb' option set will also potentially fill up tempdb;
  • DBCC DBREINDEX或具有'Sort in tempdb'選項集的類似DBCC命令也可能填滿tempdb;
  • large resultsets involving unions, order by / group by, cartesian joins, outer joins, cursors, temp tables, table variables, and hashing can often require help from tempdb;
  • 涉及聯合的大型結果集,按組/順序排列,笛卡爾連接,外連接,游標,臨時表,表變量和散列通常需要tempdb的幫助;
  • any transactions left uncommitted and not rolled back can leave objects orphaned in tempdb;
  • 任何未提交且未回滾的事務都可以在tempdb中保留孤立的對象;
  • use of an ODBC DSN with the option 'create temporary stored procedures' set can leave objects there for the life of the connection.

    使用帶有“創建臨時存儲過程”選項的ODBC DSN可以在連接的生命周期中保留對象。

    USE tempdb GO

    使用tempdb GO

        SELECT name 
            FROM tempdb..sysobjects 
    
        SELECT OBJECT_NAME(id), rowcnt 
            FROM tempdb..sysindexes 
            WHERE OBJECT_NAME(id) LIKE '#%' 
            ORDER BY rowcnt DESC
    

The higher rowcount, values will likely indicate the biggest temporary tables that are consuming space.

行數越高,值可能表示占用空間的最大臨時表。

Short-term fix

短期修復

DBCC OPENTRAN -- or DBCC OPENTRAN('tempdb')
DBCC INPUTBUFFER(<number>)
KILL <number>

Long-term prevention

長期預防

-- SQL Server 7.0, should show 'trunc. log on chkpt.' 
-- or 'recovery=SIMPLE' as part of status column: 

EXEC sp_helpdb 'tempdb' 

-- SQL Server 2000, should yield 'SIMPLE': 

SELECT DATABASEPROPERTYEX('tempdb', 'recovery')
ALTER DATABASE tempdb SET RECOVERY SIMPLE

Reference : http://sqlserver2000.databases.aspfaq.com/why-is-tempdb-full-and-how-can-i-prevent-this-from-happening.html
Other references : http://social.msdn.microsoft.com/Forums/is/transactsql/thread/af493428-2062-4445-88e4-07ac65fedb76

參考:http://sqlserver2000.databases.aspfaq.com/why-is-tempdb-full-and-how-can-i-prevent-this-from-happening.html其他參考文獻:http://social.msdn。 microsoft.com/Forums/is/transactsql/thread/af493428-2062-4445-88e4-07ac65fedb76


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2012/08/09/cf89c5a81c767d6f94337a8220c929b5.html



 
  © 2014-2022 ITdaan.com 联系我们: