Error 2558

Severity Level 16

Message Text

Extent not within segment: Object %ld, indid %d includes extents on allocation page %ld which is not in segment %d.

Explanation

This error occurs when a portion of a database resides on a segment that was not defined to contain that type of data. The database can still function, possibly generating 1105 errors. There can also be problems with recoverability. Running DBCC CHECKALLOC will find this problem. There are no run-time errors associated with this error.

Segments are used to map where future allocations of different types of data can occur. By default, when SQL Server creates a database, it creates three segments: a system segment, a default segment, and a log segment.

For example, this statement creates the log segments on the example database:

create database example
on device_1 = 10
log on device_2 = 2

The system and default segments are mapped to device_1 and the log segment is mapped to device_2. For the example database, all future space allocations for system or user objects occur on device_1, and all transaction log records are placed on device_2. Other databases can use other portions of device_1 or device_2, and these devices can have different segment mappings for that database. More than one segment can be mapped to the same device for a database.

If system or user objects are located on device_2 or transaction log records are located on device_1, a 2558 error results in the example database. Although several situations can cause a 2558 error, these are the most common:

Different data and log mapping

If this error occurred after you re-created and loaded a database from a dump, there were probably incorrect entries in the master..sysusages table. A database loaded from a dump must be created in exactly the same way as the database that was dumped. If it isn't, there might be different entries in master..sysusages and error 2558 results. Keep an up-to-date copy of the master..sysusages system table as well as scripts to re-create all databases.

The resulting master..sysusages entries for the newly created database must be exactly the same as the database that was dumped. If a 2558 error occurs, the error falls into one of two cases:

Case 1 The data and log mappings on the newly created database do not match the mappings of the dumped database. The database being loaded into was not created in the same way as the database that was dumped.

This can cause a "data on log" situation, where user or system objects are loaded into a log segment, which results in less log space available to the database. The data is still accessible, but processing might be slowed, if not totally stopped, by the shortage of log space.

There can also be a "log on data" situation, where portions of the transaction log are loaded into a data segment. This isn't as serious as the "data on log" scenario, because the portion of the transaction log on the data segment is eventually truncated via the DUMP TRANSACTION statement, which frees up the space. All future transaction log allocations will be correctly placed on the log segment.

Suppose that the above example database was altered as follows:

alter database example on device_1 = 2

The logical order of the database pages is:

A 2558 error could result if the database were dumped, then dropped and re-created with different segment mappings. For example:

create database example on device_1 = 12
log on device_2 = 2

Although both ways of creating the database (CREATE and ALTER, or only CREATE) allocate the same amount of data and log space on the same devices, the mapping of data and log space is not the same. Here is an example:

In this example, Database 1 is dumped and loaded into Database 2, resulting in incorrect mapping of data and log space.

SQL Server DUMP and LOAD statements operate at the logical page level. In this example, logical pages 5120 through 6143 on Database 1 might contain transaction log records but, when loaded on Database 2, they are mapped onto a data segment. Similarly, pages 6144 through 7167 are mapped for data on Database 1, but are mapped for log on Database 2.

If the 2 MB data segment in this example was completely full on Database 1, there would be absolutely no log space available on Database 2 after the load. Dumping the transaction log at this point would have no effect since the log segment is filled with data.

All space allocations that occur on Database 2 after the load completes are correctly mapped.

Case 2 The mapping of user-defined segments in sysusages for the database being loaded does not match the segments of the database that was dumped. This can result from:

After you execute a LOAD DATABASE statement with one of these error conditions, the 2558 error exists but is not reported until you run DBCC CHECKALLOC on the loaded database.

sp_placeobject

Error 2558 can also occur if you execute the sp_placeobject system procedure, which places future allocations for a table or index on a particular segment. It does this by updating the sysindexes.segment column to contain the number of the segment where the object was placed.

This type of 2558 error is due to existing allocations not residing on the segment specified in sp_placeobject and is not related to the segment type. There is no negative impact of this type of 2558 error and you can ignore it. For a procedure to clear the error, see the following section.

Action

The action to correct error 2558 depends on the type of page on which the error occurred. Error 2558 occurs on four types of pages:

If you have 2558 errors and cannot re-create the database from scripts or hard copy, use the following table to match the object ID value (Object in the error message) and index ID (indid in the error message) with the corresponding data page type, and then refer to the appropriate section below.

Type of data Object ID Index ID
Data or clustered index pages > 99 0 or 1
Nonclustered index pages > 99 >1 or < 255
Text or image data pages > 99 255
System table pages < 100

Data pages or clustered index pages

The error occurred on the data page or the clustered index of a user table. Resolve the problem as follows:

  1. Create a clustered index on the table. If a clustered index already exists, drop and re-create it. If not, creating one will clear the error. You can then drop the clustered index.
  2. Copy the data out of the table, drop and re-create the table, and copy the data back in using bcp or SELECT INTO.
Nonclustered index pages

The error occurred on the index of a user table. The error can be cleared by dropping and re-creating the index. Creating a clustered index causes all nonclustered indexes to be rebuilt as well. Therefore, if 2558 errors are occurring on several indexes on the same table, you can create a clustered index on that table to clear all these errors.

Text or image data pages

The error occurred on text or image data. Use one of the following methods to correct the situation:

Or

Or

System table pages

The error occurred on a system table. Recover from a known clean backup or contact your primary support provider for assistance.

Additional Information

If this error occurred after re-creating and loading a database from a dump, you can prevent it by ensuring that the entries in the master..sysusages table for the database being loaded match the corresponding entries for the database that was dumped.

More specifically, the segmap, lstart, and size columns of sysusages must be identical in content and order. Verify this before beginning the LOAD DATABASE statement.

The entries in sysusages will be correct on the database being loaded into if you execute the following with the same parameters and in the same order as on the dumped database:

Note You cannot depend on the output of the sp_helpdb system procedure to compare the contents of the sysusages table because it does not necessarily display rows from sysusages in the actual logical page order. Instead, execute direct SELECT statements against the sysusages table.

If a substantial number of 2558 errors occur due to an incorrect LOAD DATABASE action, it might be a good idea to drop and correctly re-create the database, and then reload it.