How to move the files of database which has Replication, Mirroring, Log Shipping or AlwaysOn Settings

One of the challenging tasks in the life of a DBA it’s definitely moving all or some of the files of a database from one physical location to another one because of performance issues, maintenance requirements, disk space issues, etc.

We usually move database files to another location by using Backup/Restore or Detach/Attach procedures. They are the most proper methods for most of the business cases but not for all. Let me expand on what I mean, for instance, those methods will not work with databases which have Replication, Mirroring, Log Shipping or AlwaysOn Settings because you will have to remove these settings before move them and then you should set up every setting again which could waste your time and have your database service stopped further than necessary. In this situation Backup/Restore or Detach/Attach simply is NOT an option because we need to make the database available as soon as possible.

So, what we must do in order to move files of this type of database is by modifying the physical name of each database file we want to move. For instance, in the following code I will move 4 files (3 Data Files and 1 Log File):

ALTER DATABASE SalesDB MODIFY FILE (NAME=N'SalesDB_Data01', FILENAME= N'D:\SQLData\SalesDB\SalesDB_Data01.mdf')

ALTER DATABASE SalesDB MODIFY FILE (NAME=N'SalesDB_Data02', FILENAME= N'D:\SQLData\SalesDB\SalesDB_Data02.ndf')

ALTER DATABASE SalesDB MODIFY FILE (NAME=N'SalesDB_Data03', FILENAME= N'D:\SQLData\SalesDB\SalesDB_Data03.ndf')

ALTER DATABASE SalesDB MODIFY FILE (NAME=N'SalesDB_Log', FILENAME= N'E:\SQLLog\SalesDB\SalesDB_Log.ldf')

It’s very important to verify that new database file folders already exist, if so, this should be the output results:

The file “SalesDB_Data01” has been modified in the system catalog. The new path will be used the next time the database is started.
The file “SalesDB_Data02” has been modified in the system catalog. The new path will be used the next time the database is started.
The file “SalesDB_Data03” has been modified in the system catalog. The new path will be used the next time the database is started.
The file “SalesDB_Log” has been modified in the system catalog. The new path will be used the next time the database is started.

What’s next? We must stop the SQL Engine Service and then manually move every database file to the new location we indicated in the code above. Finally, we have to start the SQL Engine service which will load the files from the new location. With this method you don’t need to remove any setting mentioned before. This is extremely effective and there’s no doubt that it will work.

Having these files moved to the new location the database will start without any problem. If not, you should make sure that the SQL Service account has Full Control permission on database files from the new location.
 
I hope this tip helps you to save time and it will ensure that your database will be available quickly.
 
I will be pleased to answer any question you may have. Thanks!.

How to test Read-Only Intent Connection from SQL Management Studio

As part of some SQL Server AlwaysOn Availability implementations, we could need to test Read-Only Intent Connection in someway and to make sure that it is working well at SQL Server level. We can verify this by using SQL Management Studio. Let me expand on what I mean, AlwaysOn Technology give us an option to implement Read-Only Intent mode to enable SQL Server to redirect read-only connections to secondary replicas, it means off-loading Read-Only workloads to secondary replicas. This is a gripping feature, isn’t it? sure, at the beginning with SQL Server 2012, it drew my attention to test it, and I verified this is truly useful for business cases where we need to have Read-Only Intent feature working properly and automatically. It couldn’t have been better when I learned that I could use SQL Management Studio to achieve my purpose.

Keep it in mind that we need to have set up Read-Only Routing List before going to test it, obviously. Now carrying on this tip, let me show you some explicit pictures where you will see which parameters you should consider.

First of all,  you need to go on “Login” tab and write the Listener Name  of your AlwaysOn Availability Group. In this example, my Listener Name is SRV1LIDBVB which represents the Virtual Server Name.

SNAGHTML19d0a26c

What’s next?,  going to “Additional Connection Parameters” tab you will see two parameters. You must write the database name for “Database” which is in your AlwaysOn Availability Group and “ReadOnly” for “ApplicationIntent”. The both parameters are separated by a command. Mind your head about it.

image

Finally, click on “Connect” and you will be connected to any secondary replica, which one replica? it depends on what you have set up in your Read-Only Routing List.

I hope you find this post practical, effective and easy to put in practice and include it in your testing plan. Let me know if you have any remark or question. Thank you.

How to change collation of all columns

Just thinking about some interesting tools that could be useful for doing some DBA tasks, I’d like to share my code to change the collation of all columns of all SQL Server tables (I mean User Tables, not System Tables).  To begin with, I will show you a basic code to filter columns by an specific collation:

select tb.schema_id, tb.name,c.name,  c.collation_name, t.name, c.max_length, c.is_nullable,c.column_id 

from sys.columns c

inner join sys.types t on t.user_type_id= c.user_type_id

inner join sys.tables tb on  c.object_id=tb.object_id

where c.collation_name is not null 

and t.is_user_defined=0 and tb.is_ms_shipped=0 and tb.name<>'sysdiagrams'

and c.collation_name<>'SQL_Latin1_General_CP1_CI_AS'

order by tb.name, c.column_id

By executing it you will list every column that has a different collation you’d like to change. Now I am going to show you the code that generates the code to change the collation of columns. After executing this code you must take the output and execute it to have your columns collation changed for a different one. In this example I am using SQL_Latin1_General_CP1_CI_AS collation as my wanted collation, I mean I want to have SQL_Latin1_General_CP1_CI_AS  as my new collation. You have to replace it according to your requirement.

select 'ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(tb.schema_id)) + '.' + QUOTENAME(tb.name) + 

' ALTER COLUMN ' + QUOTENAME(c.name) +  ' ' + QUOTENAME(t.name) + '(' + CAST( case when T.NAME='NVARCHAR' THEN  c.max_length/2 

WHEN  T.NAME='NCHAR' THEN  c.max_length/2 ELSE c.max_length  END  AS VARCHAR(10)) +')' 

 +' COLLATE SQL_Latin1_General_CP1_CI_AS' + CASE WHEN c.is_nullable =1 THEN ' NULL ' else ' NOT NULL ;' END--,  c.collation_name,c.is_nullable 

from sys.columns c

inner join sys.types t on t.user_type_id= c.user_type_id

inner join sys.tables tb on  c.object_id=tb.object_id

where c.collation_name is not null 

and t.is_user_defined=0 and tb.is_ms_shipped=0 and tb.name<>'sysdiagrams'

and c.collation_name<>'SQL_Latin1_General_CP1_CI_AS'

order by tb.name, c.column_id

Mind your head because the execution of output code could fail as some columns could have some constraints (for instance some Foreign keys, Primary Keys, Uniques, etc.)  or indexes that you may need to drop them first and then recreate them after you change the collation of the column.

Just to finish, I highly recommend testing this code on a copy of your database to check whether any error appears because of reasons explained above, then doing what’s necessary, finally being totally sure that there’s no error you can proceed with the execution on your database in production environment.

Please let me know any remark or question that you could have.  Thanks.

Reuse SQL Job creating script to create new similar ones with different Schedule ID

As we now it’s always very important to look for new ways of being more productive every day. For instance, one of our tasks as DBA is to implement SQL Backup Jobs for each database.  Personally, I like reusing code as a template to create more similar Jobs faster, that’s, create one SQL Job, generate the SQL creating script of it, replace some things, and finally execute it to create every SQL Backup Job for all databases.

After creating next SQL Jobs by reusing code you will find these SQL Jobs have the same SQL Schedule ID and it doesn’t allow to modify without affecting the rest of jobs. So, you will have to drop the SQL Schedule and create a new one. It may not be what we wanted to do because it could be harder than just modify it, so we wonder how to create SQL Jobs based on the same template and without the same SQL Schedule ID?. This post pretends to show what you might do to achieve this.

First of all, look at this picture.

29-04-2016 10-28-42

Inside the code you will see a parameter @schedule_uid which is the SQL Job Schedule ID, so what we have to do now is to “comment” this line in order to allow SQL Server to generate a new ID for each SQL Job Schedule.

image

Now you will be able to modify every Schedule for each Job and the rest of Jobs don’t inherent this change. I hope this post is useful for you and let me know any questions. Until next post, enjoy it!.

AlwaysOn AG Listener: The attempt to create the network name and IP address for the listener failed

Since SQL Server 2012 AlwaysOn technology is here with us, we’ve been working on a heap of projects to support HA + DR sceneries where I’ve had many opportunities to face with some interesting errors which challenged me to overcome as fast as possible because of the short limited time I had to have it finished. Today’s post is going to show you how I could solve one of them. I’m speaking about the following error which is raised when we have to configure AlwaysOn AG Listener:

The Windows Server Failover Clustering (WSFC) resource control API returned error code 5057.  The WSFC service may not be running or may not be accessible in its current state, or the specified arguments are invalid. 

The attempt to create the network name and IP address for the listener failed. The WSFC service may not be running or may be inaccessible in its current state, or the values provided for the network name and IP address may be incorrect. Check the state of the WSFC cluster and validate the network name and IP address with the network administrator. (Microsoft SQL Server, Error: 41009)

It could be a quite easy to fix it but it may become complicated sometimes because we don’t have more details of what causes the error, and it doesn’t give us any clue where the cause is. That’s why I am writing this post in order to try to help you.

In my experience working on this, I’ve noticed two common causes:

1. The most common cause has to be about lacking of permission for the Cluster Name Account so you have to make sure that this account has the following permissions:

1. “Create Computer” and “Read” permissions.

clip_image001

2. Once you have given right permissions and if the error is still there then you must check whether the IP Address is available to be assigned to the AlwaysOn AG Listener. It is easy to verify by making ping to IP Address which should be free. If not, ask your Administrator a new IP Address and try again.

I hope this practical post helps you. Let me any comment or question if you want to.

Until next post…. enjoy it.