Failed to automate the release of space in SQL Server databases - sql

I try to automate the process of releasing the space of the databases in a SQL server, for this I assembled the following script with 3 particular cases (according to the business rules of the institution). The first is the tempdb, I separate this database because I cannot apply thealter ... recovery (I do not know if it is necessary to apply the release of space to this database). The second rule is for a particular database BD_MAIN, which has four data files and four log files, I only apply for the last two files. The third case is by discarding, for all the remaining databases.
EXEC sp_MSforeachdb
'
use [?]
declare
#arch_1 sysname,
#arch_2 sysname,
#bd_name sysname
set #bd_name=(select DB_NAME())
set #arch_1 =(select name FROM SYSFILES
where fileid = ''1'')
set #arch_2 =(select name FROM SYSFILES
where fileid = ''2'')
-- 1st case: If the data base is tempdb:
if (#bd_name=''tempdb'')
begin
select name from sysfiles
DBCC SHRINKFILE (tempdev, 1)
DBCC SHRINKFILE (templog, 1)
end
-- 2nd case: If the data base is BD_MAIN:
else
begin
if (#bd_name=''BD_MAIN'')
begin
select name from sysfiles
DBCC SHRINKFILE (BD_MAIN4 , 1);
ALTER DATABASE BD_MAIN
SET RECOVERY SIMPLE
DBCC SHRINKFILE (BD_MAIN_log4 , 1);
ALTER DATABASE BD_MAIN
SET RECOVERY FULL
end
-- 3rd case: Another data bases:
else
begin
select name from sysfiles
DBCC SHRINKFILE (#arch_1 , 1)
ALTER DATABASE [?]
SET RECOVERY SIMPLE
DBCC SHRINKFILE (#arch_2 , 1)
ALTER DATABASE [?]
SET RECOVERY FULL
end
end
'
The problem that I have with this script is when I am in ´tempdb´, it is supposed that I should not enter the last else (for other cases), however it throws me the following error message (4th line):
DBCC execution completed. If there are error messages, consult your system administrator.
DBCC execution completed. If there are error messages, consult your system administrator.
Mens. 5058, Level 16, State 1, Line 44
The 'RECOVERY' option can not be set in the 'tempdb' database.
DBCC execution completed. If there are error messages, consult your system administrator.
You can not reduce the file '2' in the database 'model' to 128 pages, since it only contains 96 pages.
DBCC execution completed. If there are error messages, consult your system administrator.
DBCC execution completed. If there are error messages, consult your system administrator.
DBCC execution completed. If there are error messages, consult your system administrator.
DBCC execution completed. If there are error messages, consult your system administrator.
I would like to know if the code can be improved to avoid this kind of error messages since I want to incorporate it into a stored procedure or some recommendation about the release of space (how, when and when to do it).

Related

SQL server- Transaction log for database is full

I am trying to insert some data into a table in my database in sql server. It has huge amount of data, I am talking about millions of records.
I kept getting error 9002
The transaction log for database 'GCVS2' is full. To find
out why space in the log cannot be reused, see the log_reuse_wait_desc
column in sys.databases.
When I tried inserting data yesterday, it was fine with no problem, although it did take some time.
I tried it again today but kept getting this error. I checked the log file for my database, and it's auto increment is set to 10% ,unlimited. Is there any way to fix this?
You Can Truncate the transaction log. use the below query
BACKUP LOG databasename WITH TRUNCATE_ONLY
DBCC SHRINKFILE ( databasename_Log, 1)
Check here for more details
You will need to check the Recovery mode of your database. Put it in Full Recovery mode. After that, make sure there is a transaction log backup in place for your database. You will need to dig through it and make a Maintenance plan, depending upon how critical your data is. That will be the long term solution.
For time being you can shrink your log files using following DBCC command -
BACKUP LOG DBName WITH TRUNCATE_ONLY
DBCC SHRINKFILE ( DBNameLog, 1)
Or you can do it through Object Explorer. Refer to this link for details. But you will have to set your Database to Simple Recovery model to use the Shrink command

Error 8921 running DBCC CHECKDB

DBCC CHECKDB shows following error message in my sql server 2008 R2 database
Msg 8921, Level 16, State 1, Line 2
Check terminated. A failure was detected while collecting facts. Possibly tempdb out of space or a system table is inconsistent. Check previous errors.
What is the solution?
Given that DBCC CHECKALLOC fails too, with no corruption messages, your database has corrupt metadata and you need to restore from your backups (the first thing it does is run some basic checks on the three critical system tables it needs, and if they're badly broken, it will fail with message 8921). You have no other choice here - you can't run repair as you can't get DBCC CHECKDB to run.
It's possible you could narrow down which system table is corrupt using DBCC CHECKTABLE on successive object IDs from sys.objects, and then manually edit around the corruption, but that's very advanced and has a very low chance of success.
If you don't have any backups, you're going to have to create a new database and then export all the schemas and data into the new database.

An inconsistency was detected during an internal operation in database

When I execute query
Select * from TableName
I get this error :
An inconsistency was detected during an internal operation in database 'MYDABATADASE'(ID:5) on page (1:4796). Please contact technical support. Reference number 7.
How can I fix this error ?
Try to run DBCC CHECKDB and after it ends try to analyse the output (output will suggest you user actions required to fix the issues) or (and) try to restore your DB from the last known good backup.
DBCC CHECKDB('YOUR_DB_NAME') WITH NO_INFOMSGS, ALL_ERRORMSGS
There are two repair options that DBCC CHECKDB output can suggest
REPAIR_REBUILD - performs a repair that does not lead to any data
loss.
REPAIR_ALLOW_DATA_LOSS - performs a repair and fixes the
corrupted database structures, and also may results in data loss
After deciding which option to use (suppose you chose second) you need to execute code similar to this:
ALTER DATABASE [YOUR_DB_NAME] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
BEGIN TRANSACTION;
DBCC CHECKDB ('YOUR_DB_NAME', REPAIR_ALLOW_DATA_LOSS);
ALTER DATABASE [YOUR_DB_NAME] SET MULTI_USER;
COMMIT;
Note that SQLDUMPnnnn.txt is created in the SQL Server LOG directory and contains the results of the DBCC CHECKDB command and additional diagnostic output. (source)

Set database from SINGLE USER mode to MULTI USER

I need help with setting a database that was restored in SINGLE_USER mode to MULTI_USER. Every time I run
ALTER DATABASE BARDABARD
SET MULTI_USER;
GO
I get this error:
Changes to the state or options of database 'BARDABARD' cannot be made at this time.
The database is in single-user mode, and a user is currently connected to it.
It needs to be in non-SINGLE_USER mode to set it to another mode, but I can’t set the database in any another mode while it is SINGLE_USER mode.
The “user is currently connected to it” might be SQL Server Management Studio window itself. Try selecting the master database and running the ALTER query again.
That error message generally means there are other processes connected to the DB. Try running this to see which are connected:
exec sp_who
That will return you the process and then you should be able to run:
kill [XXX]
Where [xxx] is the spid of the process you're trying to kill.
Then you can run your above statement.
You can add the option to rollback your change immediately.
ALTER DATABASE BARDABARD
SET MULTI_USER
WITH ROLLBACK IMMEDIATE
GO
SQL Server 2012:
right-click on the DB > Properties > Options > [Scroll down] State > RestrictAccess > select Multi_user and click OK.
Voila!
I had the same issue and it fixed by the following steps - reference: http://giladka8.blogspot.com.au/2011/11/database-is-in-single-user-mode-and.html
use master
GO
select
d.name,
d.dbid,
spid,
login_time,
nt_domain,
nt_username,
loginame
from sysprocesses p
inner join sysdatabases d
on p.dbid = d.dbid
where d.name = 'dbname'
GO
kill 56 --=> kill the number in spid field
GO
exec sp_dboption 'dbname', 'single user', 'FALSE'
GO
This worked fine for me.
Step 1. Right click on database engine, click on activity monitor and see which process is having connection. Kill that particular user and execute the query Immediately.
Step 2.
USE [master];
GO
ALTER DATABASE [YourDatabaseNameHere] SET MULTI_USER WITH NO_WAIT;
GO
and refresh the database.
I have just fixed using following steps, It may help you.
Step: 1
Step: 2
Step: 3
Step: 4
Step: 5
Then run following query.
ALTER DATABASE YourDBName
SET MULTI_USER
WITH ROLLBACK IMMEDIATE
GO
Enjoy...!
I actually had an issue where my db was pretty much locked by the processes and a race condition with them, by the time I got one command executed refreshed and they had it locked again... I had to run the following commands back to back in SSMS and got me offline and from there I did my restore and came back online just fine, the two queries where:
First ran:
USE master
GO
DECLARE #kill varchar(8000) = '';
SELECT #kill = #kill + 'kill ' + CONVERT(varchar(5), spid) + ';'
FROM master..sysprocesses
WHERE dbid = db_id('<yourDbName>')
EXEC(#kill);
Then immediately after (in second query window):
USE master ALTER DATABASE <yourDbName> SET OFFLINE WITH ROLLBACK IMMEDIATE
Did what I needed and then brought it back online. Thanks to all who wrote these pieces out for me to combine and solve my problem.
It may be best to log onto the server directly instead of using SQL Management Studio
Ensure that the account you login as is dbowner for the database you want to set to MULTI_USER. Login as sa (using SQL server authentication) if you can
If your database is used by IIS, stop the website and the app pool that use it - this may be the process that's connected and blocking you from setting to MULTI_USER
USE MASTER
GO
-- see if any process are using *your* database specifically
SELECT * from master.sys.sysprocesses
WHERE spid > 50 -- process spids < 50 are reserved by SQL - we're not interested in these
AND dbid=DB_ID ('YourDbNameHere')
-- if so, kill the process:
KILL n -- where 'n' is the 'spid' of the connected process as identified using query above
-- setting database to read only isn't generally necessary, but may help:
ALTER DATABASE YourDbNameHere
SET READ_ONLY;
GO
-- should work now:
ALTER DATABASE Appswiz SET MULTI_USER WITH ROLLBACK IMMEDIATE
Refer here if you still have trouble:
http://www.sqlservercentral.com/blogs/pearlknows/2014/04/07/help-i-m-stuck-in-single-user-mode-and-can-t-get-out/
AS A LAST ALTERNATIVE - If you've tried everything above and you're getting desperate you could try stopping the SQL server instance and start it again
You couldn't do that becouse database in single mode. Above all right but you should know that: when you opened the sql management studio it doesn't know any user on the database but when you click the database it consider you the single user and your command not working.
Just do that: Close management studio and re open it. new query window without selecting any database write the command script.
USE [master];
GO
ALTER DATABASE [tuncayoto] SET MULTI_USER WITH NO_WAIT;
GO
make f5 wolla everything ok !
The code below has worked for me when I didn't know the specific SPID that was used to change into singleuser mode.
use master
GO
select
d.name,
d.dbid,
spid,
login_time,
nt_domain,
nt_username,
loginame
from sysprocesses p
inner join sysdatabases d
on p.dbid = d.dbid
where d.name = 'dbname'
GO
kill 52 -- kill the number in spid field
GO
exec sp_dboption 'dbname', 'single user', 'FALSE'
GO
Tried everything didn't work
Login to that server remotely as we gonna kill all connections
run the below code more than once till it returns completed and no "killing process" test anymore
reactivate it again using the code below the below code
use master GO declare #sql as varchar(20), #spid as int
select #spid = min(spid) from master..sysprocesses where dbid =
db_id('DB_NAME') and spid != ##spid
while (#spid is not null) begin
print 'Killing process ' + cast(#spid as varchar) + ' ...'
set #sql = 'kill ' + cast(#spid as varchar)
exec (#sql)
select
#spid = min(spid)
from
master..sysprocesses
where
dbid = db_id('DB_NAME')
and spid != ##spid end
then to bring it back alive
ALTER DATABASE DB_NAME SET MULTI_USER; GO
This worked fine for me
Take a backup
Create new database and restore the backup to it
Then Properties > Options > [Scroll down] State > RestrictAccess > select Multi_user and click OK
Delete the old database
Hope this work for all
Thank you
Ramesh Kumar
If the above doesn't work, find the loginname of the spid and disable it in Security - Logins
I have solved the problem easily
Right click on database name rename it
After changing, right click on database name --> properties --> options --> go to bottom of scrolling RestrictAccess (SINGLE_USER to MULTI_USER)
Now again you can rename database as your old name.
On more than 3 occasions working with SQL Server 2014, I have had a database convert to Single User mode without me changing anything. It must have occurred during database creation somehow. All of the methods above never worked as I always received an error that the database was in single user mode and could not be connected to.
The only thing I got to work was restarting the SQL Server Windows Service. That allowed me to connect to the database and make the necessary changes or to delete the database and start over.
just go to database properties
and change SINGLE USER mode to MULTI USER
NOTE:
if its not work for you then take Db backup and restore again and do above method again
*
Single=SINGLE_USER
Multiple=MULTI_USER
Restricted=RESTRICTED_USER
After going in to the Single-User mode, a client can establish only ONE connection with the SQL Server, remember that "Object Explorer" takes up a (separate) connection, so if you are trying run a Multi-User statement in a query window, you will get error that in Single-User mode you can't establish another connection.
For me this wasn't the issue though, in my case, there were few automated processes that were persistently (in every few seconds) establishing connections, so as soon as I took the DB into Single-User mode and disconnected myself, one of the processes established/occupied the connection (before I could start my Restore operation). As soon as I'd kill those connections - they'd reconnect and when I ran the Restore command, I would get the error that connection is already occupied.
To resolve this I had to write the kill statements, change of User-Mode statements and Restore operations all in one query window and when I ran them all in one go, voila!!! it worked.
Hope this helps others.
I was having trouble with a local DB.
I was able to solve this problem by stopping SQL server, and then starting SQL server, and then using the SSMS UI to change the DB properties to Multi_User.
The DB went into "Single User" Mode when i was attempting to restore a backup. I hadn't created a backup of the target database before attempting to restore (SQL 2017). this will get you every time.
Stop SQL Server, Start SQL Server, then run the above Scripts or use the UI.
I googled for the solution for a while and finally came up with the below solution,
SSMS in general uses several connections to the database behind the scenes.
You will need to kill these connections before changing the access mode.(I have done it with EXEC(#kill); in the code template below.)
Then,
Run the following SQL to set the database in MULTI_USER mode.
USE master
GO
DECLARE #kill varchar(max) = '';
SELECT #kill = #kill + 'KILL ' + CONVERT(varchar(10), spid) + '; '
FROM master..sysprocesses
WHERE spid > 50 AND dbid = DB_ID('<Your_DB_Name>')
EXEC(#kill);
GO
SET DEADLOCK_PRIORITY HIGH
ALTER DATABASE [<Your_DB_Name>] SET MULTI_USER WITH NO_WAIT
ALTER DATABASE [<Your_DB_Name>] SET MULTI_USER WITH ROLLBACK IMMEDIATE
GO
To switch back to Single User mode, you can use:
ALTER DATABASE [<Your_DB_Name>] SET SINGLE_USER
This should work. Happy coding!!
Thanks!!
What I do:
First I kill all database process, to certificate that database isn't in use.
After I alter the user mode.
Sometimes a process is quickly grabed again from an aplication, and I need run this process one more time...
Replace the expression DATABASE_NAME below, to use your database name.
--Kill process
USE Master
GO
declare #sql as varchar(20), #spid as int
select #spid = min(spid) from master..sysprocesses where dbid = db_id('DATABASE_NAME') and spid != ##spid
while (#spid is not null)
begin
print 'Killing process ' + cast(#spid as varchar) + ' ...'
set #sql = 'kill ' + cast(#spid as varchar)
exec (#sql)
select
#spid = min(spid)
from
master..sysprocesses
where
spid > 50 AND dbid = db_id('DATABASE_NAME')
and spid != ##spid
end
print 'Killing Process completed...'
GO
**--Alter user mode**
ALTER DATABASE DATABASE_NAME SET MULTI_USER;
GO
print 'Alter Database Process completed...'

SQL Server 2000 to SQL Server 2008 R2 migration

I am using SQL Server 2000 including 77 databases, and I want to migrate them to the new SQL Server 2008 R2.
I can do this operation individually with attach or restore commands. Is there any script for migrating 77 databases to the new server installed SQL Server 2008 R2.
Thank you
You could write a script to backup in a loop and restore on another server
As long as the backup files are visible to both servers. This would allow a WITH MOVE option to allow for different drives/folders.
Backups are smaller than MDFs/LDFs too to less copying
You will need to produce your own script as you would really want to do more than backup and restore.
Other things you might like to do is run DBCC UpdateUsage, set the compatibility level, update the stats, run DBCC CheckDB with Data_Purity, change the page verify option to checksum. You may have replication and full text catalogues to deal with as well. All these things would probably need to go into your script.
You would need to setup a script that performs all/some/more of the things mentionned previously on a database and then extend your script to loop through all your databases. This can be done using a combination of batch files or powershell files and utilizing sqlcmd.
For example this is one script I run after restoring the backups onto the new server. This is called from a windows batch file via sqlcmd.
USE [master]
GO
ALTER DATABASE [$(DATABASENAME)] SET COMPATIBILITY_LEVEL = 100
ALTER DATABASE [$(DATABASENAME)] SET PAGE_VERIFY CHECKSUM WITH NO_WAIT
GO
Use [$(DATABASENAME)]
Go
Declare #DBO sysname
--who is the sa user
Select #DBO = name
from sys.server_principals
Where principal_id = 1
--assign sa the DB owner
exec ('sp_changedbowner ''' + #DBO +'''')
go
--fix the counts
dbcc updateusage (0)
go
--check the db include the column value integrity
dbcc checkdb(0) With Data_Purity, ALL_ERRORMSGS, NO_INFOMSGS
go
--make sure the stats are up to date
exec sp_updatestats
Go
You could use a software tool like Sql Compare.
Failing that I would script them individually.
You could run round the internal sysobjects table and build a combined script, but I wouldn't.