Skip to content

Point41

IT Tips & Tricks

Archive

Category: SQL Server

As a software developer/architect in this era of downsizing and people becoming Jacks of all Trades, I frequently find myself in a situation where I have to do DBA stuff. In one particular case, I am maintaining two databases which are peer-to-peer replicated. The databases support a web application for a primary site and a disaster recovery (DR) site.

Though already running in production mode, the web application is still changing because new features are being added on a daily basis. As a result of this, schema changes are pushed to the database almost weekly and I just don’t have the time to maintain the SQL scripts required to keep replication in sync with the schema changes. It is much easier to just: 1) take down replication and delete the DR database, 2) update the schema on the primary database, 3) restore a new copy of the second DR from a backup of the primary, 4) reseed identity columns on the DR database, 5) set up replication from scratch.

It may sound stupid, but whatever. Setting up replication from scratch through the UI works out to be easier than maintaining the change scripts required to keep several hundred tables properly replicated while new tables are columns are being constantly added. The only pain-in-the-ass part of this method is that the identity columns of hundreds of tables in the DR database need to be reseeded each time. Fortunately this can be done quickly.

Our rule is that indentity columns of type int should have values in the range of 1 – 1073741823 on the main database, and on the second database the range should be 1073741824 and up. For bigint it should be 1 – 10737418239 on the main database and 10737418240 and up on the second database.

So for a table tbl_abc which has an identity column of type int to run the following 2 SQL statements on the DR database:


dbcc checkident('tbl_abc', RESEED, 1073741824)
dbcc checkident('tbl_abc', RESEED)

The first sets the seed value to 1073741824. However, the application might have previously failed over to the DR database and there may already be rows with identity columns having a value of 1073741824 and up. The second statement above correcly sets the seed to the next available value, if 1073741824 is already used.

The output of following SQL script will generate the pair DBCC statements for all tables in the database named ‘tbl_%’.


select
'dbcc checkident(''' + st.name + ''',RESEED,' + case when sc.system_type_id = 56 then '1073741824)' else '10737418240)' end
from sys.tables st
inner join sys.columns sc on sc.object_id = st.object_id
where st.name like 'tbl_%'
and sc.is_identity = 1

select
'dbcc checkident(''' + st.name + ''',RESEED)'
from sys.tables st
inner join sys.columns sc on sc.object_id = st.object_id
where st.name like 'tbl_%'
and sc.is_identity = 1

The output needs to be captured as text and cleaned up a little (remove headers, etc.), before being resumbitted as a SQL command. Note that if the table has many rows (over several hundred thousand), it could take a while for DBCC CHECKIDENT to complete.

The following SQL Server script enumerates the tables in a database and calls DBBC REINDEX on each one (with a fill factor of 80%). It then calls sp_updatestats too update the index statistics.

USE <database_name>

DECLARE @TableName varchar(255)

DECLARE TableCursor CURSOR FOR
SELECT table_name FROM information_schema.tables
WHERE table_type = ‘base table’

OPEN TableCursor

FETCH NEXT FROM TableCursor INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
Print @TableName
DBCC DBREINDEX(@TableName,’ ‘,80)
FETCH NEXT FROM TableCursor INTO @TableName
END

CLOSE TableCursor

EXEC sp_updatestats

To avoid your queries from running under non-optimal execution plans, the script should be run periodically, typically weekly or nightly, when the the database is not in use.

Scenario – You have successfully setup replicated SQL Server databases with ntext fields and things were going fine initially. One day you get this error in the Event Log:

Server: Msg 7139, Level 16, State 1, Line 1
Length of text, ntext, or image data ([some number larger than 65536]) to be replicated exceeds configured maximum 65536.
The statement has been terminated.

This is happeming because Max Text Replication Size by default is set to 65536 and SQL Server has attempted to replicate a row where the data in a column is greater than this size. From the SQL Server Management Studio you can view and change this setting under Server Properties | Advanced dialog.

max text repl size

Increase this number to a higher value – up to 2147483647. Make this change on all SQL Servers involved in the replication. If you don’t like UI stuff, you can also make this change via a SQL Query.

EXEC sp_configure ‘max text repl size’, 2147483647
GO

RECONFIGURE
GO