November 1, 2005 at 8:23 am
Hi,
I have created a copy of a database programmatically using asp.net. Now I need to do some checks before creating database. I need to check the size of a database that is being copied. is there a system stored procedure that returns the size of a database? After creating the database, I need to do the following things
1) shrink the database
2) detach the database
3) delete log file
Are there any stored procedures that will shrink the database and detach it?
please let me know.
Thanks,
Sridhar.
November 1, 2005 at 9:15 am
Size of db is reported using this system stored procedure
sp_helpdb
There are several ways to shrink a db, check books online for
DBCC SHRINKDATABASE
dbcc shrinkfile
A log file is an integral part of the database, you cannot just delete it unless the db has been properly detached
See sp_detach_db
November 2, 2005 at 7:00 am
The following statement will give you the currently allocated size of a database:
SELECT [maxsize] AS 'pages', (CAST([maxsize] AS bigint) * 8192) AS 'bytes'
FROM dbo.sysfiles WITH (NOLOCK)
WHERE ([status] & 64) = 0
The column [maxsize] returns the number of data pages, the second field is the number of data pages multiplied by the size of a data page. I am using 8192 hardcoded here, but you can verify this on your system using 'select [low] from master..spt_values where type = 'E' and number = 1'.
Shrinking the db is dependent on a number of factors. the amount of data, the number of files, the number of file groups and so on. in general, if you have a complex configuration, dbcc shrinkdb would be less coding, but also less efficient. if there is 1 db file and you want to drop the log file, use dbcc shrinkfile on the db file. this question can best be answered by testing.
as for dropping the log file, this can be done, but not by an operational database. the db can not operate without a log file, but i have cases where i perform a lot of work and need to reduce the size of the log file as small as possible for shipping a product. in this case, i shrink the db, detach the db using 'sp_detach_db' with the shipchecks flag set to false so that the statistics are updated. After the db is detached, i then delete the log file from disk, and re-attach the db using 'sp_attach_single_file_db'. this creates a log file, but it is minimum size without any transactions in it that can be shipped in the product. certainly this is limited in functionality, but it does address the need for having an empty tlog file without dealing with the virtual log file boundary issues.
November 2, 2005 at 8:05 am
Hi - I must be missing something on the usage of your query; I get the same results for each database I tried it on. I also was hoping for something that would give you quick size of DB (data vs. log) other than sp_helpdb.
thanks!
November 2, 2005 at 9:09 am
The original question was how big is the db. this is answered by looking at how much space is allocated for that db, the maxsize filed in the sysfiles table.
if you want the current size of a db then use this (format it as you prefer):
be aware that the results are dependent on updated table statistics. if you run this query once, get the results and then update statistics on the tables and re-run the query, you may get somewhat different results.
SELECT 'DATA = ' + CAST((SUM(CAST( AS bigint)) * 8192) AS varchar) + ' bytes'
FROM dbo.sysfiles WITH (NOLOCK)
WHERE ([status] & 64) = 0
UNION ALL
SELECT 'LOG = ' + CAST((SUM(CAST( AS bigint)) * 8192) AS varchar) + ' bytes'
FROM dbo.sysfiles WITH (NOLOCK)
WHERE ([status] & 64) <> 0
if you are getting the same from all db's then they all have the same settings.
watch that the query actually runs within the context of the desired db
November 2, 2005 at 9:12 am
I don't have something simpler than this. It shows exactly the data you would normaly found in EM clicking your database and then View->Taskpad. I use this SP to keep track of how my database has been growing in time. It collects data and inserts it in another table (at the end of the script). I run this script through a job nightly.
--------------------------
CREATE procedure DBusage
as
declare @idint-- The object id of @objname.
declare @typecharacter(2) -- The object type.
declare@pagesint-- Working variable for size calc.
declare @dbname sysname
declare @dbsize dec(15,0)
declare @logsize dec(15)
declare @bytesperpagedec(15,0)
declare @pagesperMBdec(15,0)
declare @unallocatedspace float
declare @reserved float
declare @curdate datetime
/*Create temp tables before any DML to ensure dynamic
** We need to create a temp table to do the calculation.
** reserved: sum(reserved) where indid in (0, 1, 255)
** data: sum(dpages) where indid < 2 + sum(used) where indid = 255 (text)
** indexp: sum(used) where indid in (0, 1, 255) - data
** unused: sum(reserved) - sum(used) where indid in (0, 1, 255)
*/
create table #spt_space
(
rowsint null,
reserveddec(15) null,
datadec(15) null,
indexpdec(15) null,
unuseddec(15) null
)
/*
** If @id is null, then we want summary data.
*/
/*Space used calculated in the following way
**@dbsize = Pages used
**@bytesperpage = d.low (where d = master.dbo.spt_values) is
**the # of bytes per page when d.type = 'E' and
**d.number = 1.
**Size = @dbsize * d.low / (1048576 (OR 1 MB))
*/
select @dbsize = sum(convert(dec(15),size))
from dbo.sysfiles
where (status & 64 = 0)
select @logsize = sum(convert(dec(15),size))
from dbo.sysfiles
where (status & 64 0)
select @bytesperpage = low
from master.dbo.spt_values
where number = 1
and type = 'E'
select @pagesperMB = 1048576 / @bytesperpage
select @unallocatedspace=ltrim(str((@dbsize -
(select sum(convert(dec(15),reserved))
from sysindexes
where indid in (0, 1, 255)
)) / @pagesperMB,15,2))
/*
** Now calculate the summary data.
** reserved: sum(reserved) where indid in (0, 1, 255)
*/
insert into #spt_space (reserved)
select sum(convert(dec(15),reserved))
from sysindexes
where indid in (0, 1, 255)
/*
** data: sum(dpages) where indid < 2
**+ sum(used) where indid = 255 (text)
*/
select @pages = sum(convert(dec(15),dpages))
from sysindexes
where indid < 2
select @pages = @pages + isnull(sum(convert(dec(15),used)), 0)
from sysindexes
where indid = 255
update #spt_space
set data = @pages
/* index: sum(used) where indid in (0, 1, 255) - data */
update #spt_space
set indexp = (select sum(convert(dec(15),used))
from sysindexes
where indid in (0, 1, 255))
- data
/* unused: sum(reserved) - sum(used) where indid in (0, 1, 255) */
update #spt_space
set unused = reserved
- (select sum(convert(dec(15),used))
from sysindexes
where indid in (0, 1, 255))
select @reserved = ltrim(str(reserved * d.low / 1048576,15,0) )
from #spt_space, master.dbo.spt_values d
where d.number = 1
and d.type = 'E'
-- print @unallocatedspace
-- print @reserved
select @curdate=cast(floor(cast(GetDate() as float)) as datetime)
insert into [srv-name].database.dbo._dataused values (@curdate,@reserved+@unallocatedspace,@unallocatedspace,@reserved)
drop table #spt_space
GO
November 2, 2005 at 11:02 am
ahhh ... a taste of the old 'Sybase' code base ...
sp_spaceused is still the best tool for the JOB. system table 'stuff' is going to change in 2K5 (just as it did from v6.0 to v7.0 !!!) ...
RegardsRudy KomacsarSenior Database Administrator"Ave Caesar! - Morituri te salutamus."
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply