Friday, May 10, 2013

How to move a table from one file group to another file group in SQL server?


This is one of the questions haunting me from long where-in I was not aware of how to do that and I haven’t spent time as well to find the solution, luckily i tried this time. First thing is(as far as I tried) we cannot move a table from one file to another file in a database but what we can achieve is we can move a table between file groups. Something like from PRIMARY file group to SECONDARY and so on.

How?

To move a table from Filegroup1 to Filegroup2 we have to move the CLUSTERED INDEX of the table. After that we need to move the other NON-CLUSTERED indexes as well to the new file group. This will move the entire table from one FG to another FG.

Here I will move a table named ‘SalesOrderDetail’ of ‘AdventureWorks2012’ sample database from PRIMARY file group to SECONDARY file group. The below commands I have tried on both 2008 and 2012, they are valid for both versions.

Step: 1

To get Index Details:

To get the details of indexes along with file group information I am using below query. It will give table name, type of index, index name and in which file group it is currently in.

SELECT      'Table Name' = OBJECT_NAME(INX.object_id),

            'Index Name' = INX.name,

            'Type Of Index' = INX.type_desc,

            'FileGroup Name' = FGS.name

FROM        sys.indexes INX

INNER JOIN  sys.filegroups FGS ON INX.data_space_id = FGS.data_space_id

WHERE       INX.object_id = OBJECT_ID('[Sales].[SalesOrderDetail]')
 
 


As we can see in above capture the table has 3 indexes and all are in PRIMARY FG.

Creation of secondary file group and secondary file:

To create SECONDARY file group we can right click on the database and select ‘Properties’, then click on ‘Filegroups’, then click on ‘Add’ button and under the ‘Rows’ enter the name of the new file group, here I am giving the name as ‘SECONDARY’ itself and click ‘OK’. This will create new file group.
 



Adding file to new FG:

To create secondary data file and add it to new FG we can use below command:

Use AdventureWorks2012

ALTER DATABASE AdventureWorks2012

ADD FILE

( NAME = [AdventureWorksDW2008R2_Data2],

FILENAME = 'C:\SQLServer2012\AdventureWorks2012_Data2.mdf')

TO FILEGROUP [SECONDARY]

While creation itself we can specify the settings of the new data file like how it should grow, what should be its initial size and all. If we don’t specify those values it will take all default values. Through the above command a new file will be created with the name ‘AdventureWorks2012_Data2’ and it will reside in the location specified.

Moving of CLUSTERED INDEX:

After creating secondary FG and adding file to it , to move table ‘SalesOrderDetail’ to new FG we first need to move CLUSTERED INDEX of that table with below command:

CREATE UNIQUE CLUSTERED INDEX [PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID]
 ON [Sales].[SalesOrderDetail]
(
   [SalesOrderID] ASC,
      [SalesOrderDetailID] ASC
) WITH (DROP_EXISTING = ON,PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,
 ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)
ON [SECONDARY]

In the above command the 2 things important are DROP_EXISTING = ON this will create new one by dropping the existing one and ON [SECONDARY] this will create it in SECONDARY file group. With above command we are trying to move the ‘[PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID]’ to new FG. The index names can be obtained from same query of Step:1.

Note: If the table is very huge it will be faster if we truncate (Depends on wether you are allowed or not to TRUNCATE) the table before moving.

Once the command completes successfully if we run the query of step 1 it will give below results:



As we can see the CLUSTERED INDEX  has been moved to new FG. Now in the same way we need to move the other NON-CLUSTERED indexes as well to new FG.

CREATE UNIQUE NONCLUSTERED INDEX [AK_SalesOrderDetail_rowguid] ON [Sales].[SalesOrderDetail]
(
      [rowguid] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF,
 IGNORE_DUP_KEY = OFF, DROP_EXISTING = ON, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON,
 ALLOW_PAGE_LOCKS  = ON) ON [SECONDARY]
GO
CREATE NONCLUSTERED INDEX [IX_SalesOrderDetail_ProductID] ON [Sales].[SalesOrderDetail]
(
      [ProductID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF, DROP_EXISTING = ON, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON,
ALLOW_PAGE_LOCKS  = ON) ON [SECONDARY]
GO

After moving NON-CLUSTERED indexes as well we can verify with same query:

 

In capture we can see now all the indexes have been moved to new FG.

The same has to be done for all the indexes of the table. For moving of NON-CLUSTERED indexes just script out the existing indexes and set the 2 options as DROP_EXISTING = ON and ‘ON [SECONDARY]’.

 

Thanks!!

Tuesday, April 23, 2013

How to mount new partition/volume as a folder in Windows?


If you open ‘Server manager’ after logging into Windows 2008 server and under ‘Storage’ section once we click on ‘Disk Management’ on right side we can see all the drives of the machine and below to that we can see all the disks available. Once a new partition is added or any unallocated partition already exists in machine we can find it if we scroll down. If unallocated partition exists it shows like below capture:


In my case I have 2 disks Disk 15 and 16 which have 100GB and 400GB of space which are currently un-allotted to any of the folder or drive. My requirement is to allot this 400GB of space to the AdventureWorks folder which is located at C:\SQL2K8\AdventureWorks).

To achieve this right click on the 400GB new volume in ‘server manager’ and select ‘New Simple Volume’ as shown in below capture:



Once you click on this it will open simple volume wizard, in the window check on the button ‘Mount in the follow empty NTFS folder’ and click on ‘Browse’ button, this open the drive and folders available in machine and in it browse to the folder for which you want to allot space, in my case I need to open C drive and SQL2K8 folder and select ‘AdventureWorks’ folder after that click on ‘OK’.




In ‘Format Partition’ window check the ‘Format this volume with …’ option and select ‘File System’ as ‘NTFS’ and ‘Allocation Unit Size’ as ‘64k’ and ‘Volume Label’ can be left unattended and check the ‘Perform a quick format’ option.

Note: The options to be selected in this windows may change based on your server settings and standards.



Then proceed clicking next and it will be done. To verify whether it has been allocated properly or not go to folder right click click ‘Properties’ and click on ‘Properties’ and then you can see the folder has free space of 400GB (as per my case here).

Thanks!!

#mountingdrive

Friday, March 1, 2013

Moving of data/log files to another drive of SQL Server 2000 server.


This is quite old topic but we never know which task you have to face as a DBA as I did recently J. In case of latest versions we can use ‘ALTER DATABASE’ command to move the database as discussed in another article. But this bit different and easy in SQL Server 2000 here we need to follow below steps to move a database files either data file or log file from one drive to another drive.

1.    Detach the database

Command: sp_detach_db ‘database name’

2.    Copy the required file(Data or Log file) to new location manually.

3.    Attached the database with below command

Sp_attach_db ‘database name’, ‘new location of data file’, ‘new location of log file’

Eg: Let’s say we want to move the ndf file and log file of Test database from a different location to the new location ‘C:\SQL2K\’, so the command will be like below:

 sp_attach_db ‘TestDB’, ‘C:\SQL2K\Test.mdf’,’C:\SQL2K\Test.ndf’,’C:\SQL2K\Test.ldf’

Note: After attaching the database delete the file from old locations.

Incase if the database of SQL Server 2000 version is involved in replication as in my case we first have to disable the replication obviously. To disable replication SQL 2K version please follow below setps:

sp_removedbreplication 'database name'

Go

exec sp_configure 'allow updates',1

RECONFIGURE WITH OVERRIDE

Go

Update sysobjects set replinfo = 0 where replinfo != 0

UPDATE syscolumns SET colstat = colstat & ~4096 WHERE colstat & 4096 <>0

Go

exec sp_configure 'allow updates',0

RECONFIGURE WITH OVERRIDE

Incase if the sp_configure command throwing error please execute it in new query window. After executing above queries DB will be out of replication but to remove completely you have to disable it from the server properties and select ‘Disable All’ options, based on the size of the database this disabling will take time and as it is old version sometimes the session will hang but once entire replication set up is disabled session will be back to normal.

Thanks!!