Warning: This document has not been reviewed. Treat it as alpha-test quality information and report any problems and suggestions to bret@sybase.comIt has historically been difficult to shrink any database except tempdb (because it is created fresh every boot time). The two methods commonly used have been:
This technote outlines a third possibility that can work in most cases.
A trivial case: An example of a time when you can easily shrink a database is if you have just altered it and are sure there has been no activity on the new fragment. In this case, you can directly delete the last row in sysusages for the db (this row was just added by alter db) and reboot the server and it should come up cleanly.
Note: If any of the fragments you are using have user defined segments on them, drop those segments before doing this.
Ensure that there is at least one data (segmap 3) and one log (segmap 4) fragment, or one mixed (segmap 7) fragment.
If the server has been in use for some time, you can shrink it by deleting rows from sysusages for the db, last rows first , after making sure that no objects have any allocations on the usages.
Find the extent with the same value as the lstart of the first fragment you plan to drop. You need to migrate every object appearing from this point on in the output.
Objids other than 0 or 99 are objects that you must migrate or drop. You can migrate a user table by building a new clustered index on the table (since the segmap was changed, the new allocations will not go on this fragment).
You can migrate some system tables (but not all) using the sp_fixindex command to rebuild it's clustered index. However, there are a few system tables that cannot have their clustered indexes rebuilt, and if they have any allocations on the usage, you are out of luck.
If the objid is 8, then it is the log. You can migrate the log by ensuring that another usage has a log segment (segmap 4 or 7). Do enough activity on the database to fill an extents worth of log pages, then checkpoint and dump tran.
Once you have moved all the objects, delete the row from sysusages and reboot the server.
Run dbcc checkdb and dbcc checkalloc on the database to be sure you are ok, then dump the database again.