Search This Blog

Showing posts with label SQL. Show all posts
Showing posts with label SQL. Show all posts

Monday, October 15, 2018

Availability Groups–Not preferred replica

Came across an issue where are AG failed over, but 4 of 47 databases decided the local secondary db replica was not preferred and set their preferred replica to DR.

AG backup preferences had been correctly set, and in the past this database AG had happily failed over multiple times without issue.

The AG housed 47 databases, with only 4 decided to go to DR??

In the end I have now idea why or how SQL decided that these 4 should be preferred at DR site, and the other 43 were on the local secondary.

image

In the end I resolved by manually forcing a failover back to the current local secondary replica (DB02). When this was the primary, I then failed back to DB02. I did this just to ensure there wasn’t an issue failing over in a certain direction.

To check that all databases were correctly set I created the following scripts that will list the value of sys.fn_hadr_backup_is_preferred_replica

EXECUTE master.sys.sp_MSforeachdb 'USE [?]; DECLARE @dby VARCHAR(max); SET @dby=DB_NAME(); SELECT @dby;SELECT sys.fn_hadr_backup_is_preferred_replica (@dby);'

This made it easy to confirm all servers and database were correctly setup.

Still none the wiser how it can get so muddled.


Share/Bookmark

Tuesday, May 30, 2017

Check Backup\Restore status

When running the AG wizard it is not clear what the percentage completion figure is of each stage.

Use the query below to examine the status of backup and restore operations.

SELECT session_id as SPID, command, a.text AS Query, start_time, percent_complete, dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a WHERE r.command in ('BACKUP DATABASE','RESTORE DATABASE')

 

 

Ref:https://www.mssqltips.com/sqlservertip/2343/how-to-monitor-backup-and-restore-progress-in-sql-server/


Share/Bookmark

Monday, June 27, 2016

SQL Server: Allow readonly access to all databases (including future)

Recently had to setup readonly access to all databases on a SQL Server, in the past this would have involved assigning roles to a login and that login to all databases, and then repeating for all new databases.

In SQL 2014 a new command allows for this to be simplified.

GRANT CONNECT ANY DATABASE TO [domain\AD-Group]

GO
GRANT SELECT ALL USER SECURABLES TO [domain\AD-Group]

ref: http://www.sqlservercentral.com/articles/Security/111116/


Share/Bookmark

Thursday, July 07, 2011

SQL Server- Creating Multiple logins at one time for multiple databases

I recently had to create a whole number of logins for a range of databases. So I developed this script that would loop through all the user databases on a server and create a login based on database name, create a random password for that login, assign the login to the appropriate database (user) and assign appropriate database roles.

It can be run multiple times and will only create logins/users that don’t exist. It will however apply the database roles to every user it is specified to create. (i.e it will apply to users it created in previous runs).

In addition the script creates a custom database role, to allow execute permissions for running stored procedures and functions.

The script will output username and passwords created

 

DECLARE @username varchar(50)
DECLARE @dbRole varchar(50)
DECLARE @vpassword varchar(8)
DECLARE @SQL varchar(max)
DECLARE @DatabaseName varchar(MAX)
DECLARE @output varchar(max)
SET @output = ''
DECLARE @uniquepassword uniqueidentifier
SET @uniquepassword = NEWID()
SET @dbRole = 'db_executor'
DECLARE my_cursor CURSOR FOR
SELECT CAST([Name] AS varchar(MAX)) AS databasename
FROM sys.sysdatabases
--only user databases
WHERE DBID>4 AND [NAME] NOT LIKE '$'
OPEN my_cursor
FETCH NEXT FROM my_cursor
INTO @DatabaseName
WHILE @@FETCH_STATUS = 0
BEGIN
	SELECT @uniquepassword = NEWID()
	SELECT @vpassword = LEFT(@uniquepassword, 8)
--Check if login exists, if not create login for server
	IF NOT EXISTS(SELECT name FROM master.dbo.syslogins WHERE name = @DatabaseName)
	BEGIN
		SET @SQL = 'USE MASTER; CREATE LOGIN ' + @DatabaseName + ' WITH PASSWORD = ''' + @vpassword + ''', DEFAULT_DATABASE=[' + @DatabaseName + '], DEFAULT_LANGUAGE=[English], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF';
		EXECUTE(@SQL);
		SET @output = @output + CHAR(13) + CHAR(10) + 'LOGIN:' + CHAR(9) + CHAR(9) + @DatabaseName;
		SET @output = @output + CHAR(13) + CHAR(10) + 'PASSWORD:' + CHAR(9) + @vpassword;
	END
--Check if user exists, if not create user in database
	SET @SQL = 'USE ' + @DatabaseName + ';
	IF NOT EXISTS(SELECT ' + @DatabaseName + '.sys.database_principals.name FROM ' + @DatabaseName + '.sys.database_principals WHERE ' + @DatabaseName + '.sys.database_principals.name = ''' + @DatabaseName + ''')
	BEGIN
		USE ' + @DatabaseName + ';
		CREATE USER ' + @DatabaseName + ' FOR LOGIN ' + @DatabaseName + '
	END'
	EXECUTE(@SQL);
--Check if db_executor role exists, if not create role in database and then assign execute permissions
	SET @SQL = 'USE ' + @DatabaseName + ';
	IF NOT EXISTS(SELECT 1 FROM ' + @DatabaseName + '.sys.database_principals WHERE ' + @DatabaseName + '.sys.database_principals.name = ''' + @dbRole + ''' AND [TYPE] = ''R'')
	BEGIN
		CREATE ROLE ' + @dbRole + ';	
	END
	GRANT EXECUTE TO ' + @dbRole + ';'
	EXECUTE(@SQL);
	SET @SQL = 'USE ' + @DatabaseName + '; EXEC sp_addrolemember @rolename = ''db_datareader'' , @membername = ''' + @DatabaseName + '''';
	EXECUTE(@SQL);
	SET @SQL = 'USE ' + @DatabaseName + '; EXEC sp_addrolemember @rolename = ''db_datawriter'' , @membername = ''' + @DatabaseName + '''';
	EXECUTE(@SQL);
	SET @SQL = 'USE ' + @DatabaseName + '; EXEC sp_addrolemember @rolename = ''db_executor'' , @membername = ''' + @DatabaseName + '''';
	EXECUTE(@SQL);
	
	FETCH NEXT FROM my_cursor
	INTO @DatabaseName
END
CLOSE my_cursor
DEALLOCATE my_cursor
/*This output statement will contain the usernames and passwords created for the users*/
SELECT @output

Share/Bookmark