Wednesday, March 27, 2013

Move SQL Server transaction log files to a different location via TSQL


To optimize I/O performance of a database, it's always a good idea to keep LOG file & DATA file in separate physical drives. 

The transaction log file records every data change and DML transaction executed in the database.  Writing to the transaction log file is sequential in nature as compared to the database files which are typically random I/O.  As such, placing the log file on separate physical disk from database will allow the disk to work in sequential manner and perform optimally.  

I'm going to show a demonstration of moving LOG files to another drive.


1: Capture database and transaction log file information

USE AdventureWorks
GO
sp_helpfile
GO

2: Set database to single user mode and detach database

Use MASTER
GO
-- Set database to single user mode
ALTER DATABASE adventureWorks
SET SINGLE_USER
GO
-- Detach the database
sp_detach_db 'AdventureWorks'
GO

*** Now the database is detached.  Once the detach process is completed, then you can copy and paste the new transaction log file then delete the old transaction log file via Windows Explorer.  Once this is completed, we can attach the database with SQL Server database log file at new location with the following script:

3: Attach database with log file at new location

USE master
GO
-- Now Attach the database
sp_attach_DB 'AdventureWorks',
'D:\Program Files\Microsoft SQL Server\MSSQL\Data\AdventureWorks_Data.mdf',
'E:\Move LogFile here through T-SQL\AdventureWorks_Log.ldf'
GO

4. Validate the LOG moving

After the final attach command  transaction log file has been moved to new location and database is operational with log file on new location.  Verifying the new database transaction log location can be accomplished by re-running 

USE AdventureWorks
GO
sp_helpfile
GO

Thursday, March 14, 2013

Bringing a database out of Restoring state in SQL Server



What if I restored a database with “NO RECOVERY” option keeping in mind that I’d keep continuing with another Differential backup set / Transactional backup set next. But then I’ve decided not to proceed further?

At this moment, database is in “Restoring” state and inaccesible.

I need to run following script bringing a database back from restoring state to normal.


RESTORE DATABASE
WITH RECOVERY

MSSQL Server : The log or differential backup cannot be restored because no files are ready to rollforward

I was facing following error while restoring Differential backup.

Restore failed for Server ''. (Microsoft.SqlServer.Smo) Additional Information: System.Data.SqlClient.SqlError: The log or differential backup cannot be restored because no files are ready to rollforward. (Microsoft.SqlServer.Smo) 

The reason for this erro is: no database that was left in non-operational mode, and thus has not been cleaned up such that uncommitted transactions have not been rolled back. 

The easy way to reproduce this error is to 

-Backup the database using full recover mode 
- Do full and differential backups. 
- Restore the DB, First from Full backup then Differential

I got the above error while trying to restore the differential backup (after you just restored the full backup). 

Reason for the error:

I restored the Full backup with Recovery option. It must be restored with NORECOVERY option to allow rest of the backup sets to be restored (Differential/Transactional)

In the Microsoft SQL Server Management Studio there are three options on the Option "page" while restoring a database. 

Option 1 (the default): Leave the database ready to use by rolling back uncommitted transactions. Additional transaction logs cannot be restored.(RESTORE WITH RECOVERY) 

Option 2: Leave the database non-operational, and do not roll back uncommitted transactions. Additional transaction logs can be restored.(RESTORE WITH NORECOVERY) 

To properly restore a database that is backup up using full recovery mode with full and differential backups, here are steps:

Restore Full Backup:

  1. Open the Restore Database window in Microsoft SQL Server Management Studio
  2. Ensure the To database field is filled in with the name you want.
  3. Choose From device as the Source for restore.
  4. Choose the full backup file you want to restore. In most cases this is the most recent full backup file.
  5. Click the Options page on the left navigation.
  6. Choose Leave the database non-operational, and do not roll back uncommitted transactions. Additional transaction logs can be restored.(RESTORE WITH NORECOVERY)
Restore Differential backup:
  1. Open the Restore Database window in Microsoft SQL Server Management Studio
  2. Ensure the To database field is filled in with the name you want. The same that you specified in step 2 for the Restore Full backup
  3. Choose From device as the Source for restore.
  4. Choose the differential backup file you want to restore. In most cases this is the most recent differential backup file.
  5. Click the Options page on the left navigation.
  6. Choose the default: Leave the database ready to use by rolling back uncommitted transactions. Additional transaction logs cannot be restored.(RESTORE WITH RECOVERY) 

If you want to restore Transactional log after Differential backup restore, then Choose "RESTORE WITH NORECOVERY" instead of "RESTORE WITH RECOVERY".

RESTORE WITH RECOVERY Needs to be the final step of a recovery process.

MSSQL Server: The tail of the log for the database "DATABASE" has not been backed up.

I was facing the following error error when attempting to restore a database in Microsoft SQL Server:

System.Data.SqlClient.SqlError: The tail of the log for the database "DATABASE" has not been backed up. Use BACKUP LOG WITH NORECOVERY to backup the log if it contains work you do not want to lose. Use the WITH REPLACE or WITH STOPAT clause of the RESTORE statement to just overwrite the contents of the log.


Solution:

Select "Overwrite the existing database" from Restore option.



This will overwrite the tail of of database log , as my DB is corrupted and wanted to restore from last full backup so it's fine for my case.

Friday, March 08, 2013

MSSQL Linked Server error: The OLE DB provider "OraOLEDB.Oracle" for linked server supplied inconsistent metadata for a column


I was trying to pull data from Oracle to MSSqlserver database using Linked server.

select * from [LINK_NAME]..SCOTT.DESCRIPTION;

But it was failing with the below error:

Msg 7356, Level 16, State 1, Line 1
The OLE DB provider "OraOLEDB.Oracle" for linked server "LINK_NAME" supplied inconsistent metadata for a column. The column "MANUFACTURER_NAME" (compile-time ordinal 6) of object ""SCOTT"."DESCRIPTION"" was reported to have a "LENGTH" of 100 at compile time and 200 at run time.

Not quite sure about the column metadata inconsistency the error reported. But got the following workaround using OPENQUERY option.

Here’s how it worked.
Select * from OPENQUERY(LINK_NAME,’SELECT * FROM SCOTT.DESCRIPTION’);

Thursday, March 07, 2013

MS SQLSERVER to ORACLE connectivity with Linked Server configuration:




1. Install Oracle Client where MSSQLSERVER is running. I've used 11.2.0 client for my case.

2. Add oracle TNS Entries for the target Oracle Database. TNS location would be:

$ORACLE_HOME/network/admin/tnsnames.ora

Here is a sample TNS file. You need to copy this from the oracle server where you want to connect.
oraLab01 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = oralab01)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = lab.com)
    )

3. Now start configuring mssql server LINKED SERVER.

Server Objects --> Linked Servers -->Right click on Linked Servers --> New Linked Server

Here you need to mention the link name, provider name etc. As I’m connecting to Non MSSQL so I had to select "Other data Source" as server type. 

4. Select Oracle Provider for OLE DB from Provider drop down.
Type data source & provider string similar to the TNS file.





5. Click Security from left side. And select "Be made using security context" then Type username & password.




6. Click Provider --> OraOLEDB.Oracle --> Right click-->Properties --> check "Allow inprocess"-->OK

7. Right click on newly created connection ---> Test Connection ---> Success!!!

Now you can either browse the tables from Linked Server connection or you may run following to select your tables.

select * from [oralab01]..scott.tiger;