I regard this as a merge replication BUG in SQL server, and it is affecting our SQL database upgrades significantly.
To reproduce the bug:
- Add, drop or change any merge article
- ALTER any stored procedure, trigger, view, function, other programmability object
- [a sync from subscribers at this point will not get the changes from 2, a new snapshot is required]
- Run the Snapshot Agent
- Sync a subscriber
- The subscriber will NOT have the changes from 2
If the snapshot agent is run in between 1 and 2, then changes are applied to the subscriber.
Querying the sysmergeschemachange table at the published database I can see what is happening here:
Normally if a programmability object's schema is altered, a row is added with the next SchemaVersion to this table right away; the row is literally the ALTER script to apply the change. Syncing a subscriber will pull this change row to catch up to the latest schema version, and the change is applied.
The BUG is that as soon as any merge article is dropped, added, or changed, the snapshot is 'invalid' and is marked as such. Any subsequent schema changes are not then written to the sysmergeschemachange table and nothing gets applied. When the snapshot is rerun, new rows will be added to, and rows removed from, sysmergeschemachange for the article changes made... The BUG is that the changes made using ALTER <programmability object> are only made to the OLD snapshot file which is still referenced in the sysmergeschemachange table with the same schema version; and this version number does not get changed. There is no ALTER script added as a later row in the table as would happen if the snapshot had not been invalidated. This is no use to existing subscribers, as they are already beyond that schema version; and they thus do not get the change. The only way they can get the change is if they are fully reinitialized, and thus pull the entire snapshot again; but this is not a feasible solution for a very large database.
All I can currently do is to drop additional articles for the objects altered, and recreate them so that they are added as later schema version rows to the sysmergeschemachange table. This is far from ideal, for in the case of a table trigger, I have to drop the table article, which means I have to also every other object article that is dependent on that table, and all those dependent on those etc.
A fix for the BUG would be to:
- either make sure that the altered object's snapshot schema gets a new schema version
- or to make sure the ALTER script is still added as a new schema version row in the event that the snapshot is invalidated
Personally I prefer the second option as changing the order of scripts messes with dependencies.
We are significantly affected by this, as we have an large database application under constant development to which we make schema changes to all objects. To makesignificant changes to a table for example, we must first drop the merge article for it so we can use the create new table, copy data and rename trick. Stored procedures, triggers and views then need changing due to the revised table schema... these changes do not get applied to subscribers due to the above bug. We cannot make the changes in any other order, as the changes to the views for example are dependent on the table schema changes.
I was not permitted to submit this as a bug for some reason at connect.microsoft.com; despite my being part of an organization with a competency.
Update: I just managed to submit this also as a bug at: https://connect.microsoft.com/SQLServer/feedback/details/3062595