Restore failing when db includes a database trigger

  • Hello all.

    We're using SQL Server 2005 sp3.

    We've recently added a database trigger for some of our databases. The triggers fires on any DDL event and writes a record to a table in a separate database (which I call DB_AUDIT).

    Whenever we restore one of our databases with this new database trigger onto another machine, we get the following error ...

    Restore failed for Server 'MYSERVER'. (Microsoft.SqlServer.Smo)

    System.Data.SqlClient.SqlError: Target string size is too small to represent the XML instance (Microsoft.SqlServer.Smo)

    The DB_AUDIT database exists on the machine we are restoring to.

    Has anybody come across this before?

  • It looks like in the trigger is trying to insert xml data into a column. However the length of the column is too small to hold the xml data. Therefore the trigger is failing.

    Increase the legnth of that column and restore again.

  • Thanks for the response. However, I am still unclear why this would be happening during a database restore.

  • The database restore would trigger a DDL event since there is essentially a new database being created (and one being dropped).

  • Hi Steve,

    Thanks for responding.

    I must admit that I am still confused, however. If I have set up a DDL trigger with database scope (as opposed with server scope), then how is it that a database restore if causes the trigger to fire?

    I must be missing something.

    - Mike

  • What type of DDL trigger did you create?

    Remember, even if you're talking about the trigger being set up on a database scope, if the DDL trigger has anything to do with dropping tables / creating tables, dropping triggers / creating triggers, anything of that nature, then a restore, which drops ALL objects and then recreates them, will trigger your DDL trigger.

    Is the DDL trigger stored in the database you're restoring? Easiest way to check (if you still have access to the original DB) is to search sys.Triggers in that database. If so, you're stuck. The trigger will probably fire no matter what you do. If you've put the DDL trigger on your audit DB, though, try disabling it during the restore. See if that works.

    Brandie Tarvin, MCITP Database AdministratorLiveJournal Blog: http://brandietarvin.livejournal.com/[/url]On LinkedIn!, Google+, and Twitter.Freelance Writer: ShadowrunLatchkeys: Nevermore, Latchkeys: The Bootleg War, and Latchkeys: Roscoes in the Night are now available on Nook and Kindle.

  • Hi Brandie. Thanks for the response.

    My approach was to create a database DDL trigger on select databases and have the trigger log the changes to a common database, DB_AUDIT.

    I didn't want to have a server scope DDL trigger (just yet) but I'm thinking that would be the better way to go.

    It would be nice to be able to set a server scope trigger that only fires for events from select databases. I don't think this is possible.

    Just to reiterate, the problem occurs when I try to restore one of the databases that has this trigger onto a test machine (which also has the DB_AUDIT database). Or stated another way, I have the DDL trigger set up on 3 databases on the production server (call it server A) and I want to backup and restore one of these database on a test server (call it server B). Both server A and B have the DB_AUDIT database.

    The trigger is as follows ...

    USE [OPS_TOFS]

    GO

    /****** Object: DdlTrigger [ddltrg_CREATE_LOG] Script Date: 11/20/2007 09:39:08 ******/

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    CREATE TRIGGER [ddltrg_CREATE_LOG] ON DATABASE -- Create Database DDL Trigger

    FOR DDL_DATABASE_LEVEL_EVENTS

    AS

    SET ARITHABORT ON

    SET NOCOUNT ON

    DECLARE @xmlEventData XML

    -- Capture the event data that is created

    SET @xmlEventData = eventdata()

    -- Insert information to a EventLog table

    INSERT INTO DB_AUDIT.dbo.tblDDLEventLog

    (

    EventTime,

    EventType,

    ServerName,

    DatabaseName,

    ObjectType,

    ObjectName,

    LoginName,

    UserName,

    CommandText

    )

    SELECT REPLACE(CONVERT(VARCHAR(50), @xmlEventData.query('data(/EVENT_INSTANCE/PostTime)')),

    'T', ' '),

    CONVERT(VARCHAR(50), @xmlEventData.query('data(/EVENT_INSTANCE/EventType)')),

    CONVERT(VARCHAR(25), @xmlEventData.query('data(/EVENT_INSTANCE/ServerName)')),

    CONVERT(VARCHAR(25), @xmlEventData.query('data(/EVENT_INSTANCE/DatabaseName)')),

    CONVERT(VARCHAR(25), @xmlEventData.query('data(/EVENT_INSTANCE/ObjectType)')),

    CONVERT(VARCHAR(50), @xmlEventData.query('data(/EVENT_INSTANCE/ObjectName)')),

    CONVERT(VARCHAR(25), @xmlEventData.query('data(/EVENT_INSTANCE/LoginName)')),

    CONVERT(VARCHAR(15), @xmlEventData.query('data(/EVENT_INSTANCE/UserName)')),

    CONVERT(VARCHAR(MAX), @xmlEventData.query('data(/EVENT_INSTANCE/TSQLCommand/CommandText)'))

    GO

    SET ANSI_NULLS OFF

    GO

    SET QUOTED_IDENTIFIER OFF

    GO

    ENABLE TRIGGER [ddltrg_CREATE_LOG] ON DATABASE

    BTW, I can recover the database following the error during restore simply by bringing it back online, which puts it into single user mode, and then going to database properties and changing the Restrict Access value from Single_User to Multi_User. However, this is less than ideal.

    - Mike

  • The simplest solution I can think of is to disable the DDL trigger on the Production DB, backup the production DB with the trigger disabled, re-enable the trigger on your Production DB, then restore the backup where the trigger is disabled.

    This should allow you to restore without the trigger going off.

    Brandie Tarvin, MCITP Database AdministratorLiveJournal Blog: http://brandietarvin.livejournal.com/[/url]On LinkedIn!, Google+, and Twitter.Freelance Writer: ShadowrunLatchkeys: Nevermore, Latchkeys: The Bootleg War, and Latchkeys: Roscoes in the Night are now available on Nook and Kindle.

  • Hello again.

    I took your suggestion and made it work. I added two new steps to the daily backup job for the databases having the trigger. The first new step disables the DDL trigger, the next step backs up the db and the second new step enables the DDL trigger.

    This way, I can restore the database to my test environment without any problems. It does not have the trigger enabled but that's okay.

    It is not as elegant as I'd like but it will do for now.

    Thanks.

  • I'm glad it worked.

    One thing I would do, if I were you, is to head out to MS's bugs & suggestions forum and see if anyone has reported this as a problem before. If not, you might want to report it as either a bug or a suggestion and see what the Microsoft crew has to say about it.

    URL is: http://connect.microsoft.com/SQLServer and click on "Submit Product Feedback". You need a live account to log into the site.

    Brandie Tarvin, MCITP Database AdministratorLiveJournal Blog: http://brandietarvin.livejournal.com/[/url]On LinkedIn!, Google+, and Twitter.Freelance Writer: ShadowrunLatchkeys: Nevermore, Latchkeys: The Bootleg War, and Latchkeys: Roscoes in the Night are now available on Nook and Kindle.

  • You might be able to rewrite your trigger to avoid throwing errors. Instead of using "CONVERT(VARCHAR(25),..." you might try "LEFT(CONVERT(VARCHAR(max),...), 25)". Or use BEGIN TRY ... BEGIN CATCH to handle the error.

  • problems probably got to do someting with xml u r inserting rather than the trigger. I did not get this error. This i what i did .

    Created a new db and wrote a DDL trigger with database scope for DROP_TABLE.

    backed up this db (which has DDL Trigger) and restored it to another blank db (new db). It restored the database succesfully.

    "Keep Trying"

Viewing 12 posts - 1 through 11 (of 11 total)

You must be logged in to reply to this topic. Login to reply