Database corruption - c#

I am planning to use localdb for next project and thinking of making rotating backup of database (it will be detached normally and only attached when software is running). And I was thinking how to do automatic restore from backup. This required me to know if database is corrupted. And I can't find anything about this subject.
My guess, peoples don't care on that level about database integrity. Backup and maintenance is a job for IT, there are dozens of tools for SQL Express.
My database will be local on PC and not big. I want to make it very simple:
detect if database is corrupt (how?)
offer user an option to restore database from most recent backup (this is easy)
P.S.: perhaps I don't know something about sql express, localdb, linq-to-sql. This is why question is very generic.
After getting answer I'll go with simple options:
if database can't be opened and file exists - database is corrupted, offer restore (not exists - create empty database and do initial setup);
provide following options (if user noticed something unusual or get errors during update, etc.): to check database DBCC CHECKDB (0, REPAIR_REBUILD) (could be good to try first) or to restore.
Automatic detection seems costly. Rather keep weekly/montly backup for manual restoration (if that would be really necessary for old data) and create mdf-file backup every run to minimize loss to 1 day maximum (which in my case is totally fine for an abnormal situation like database corruption).

I am planning to use localdb for next project a
You mean you plan to run a database that is explicitly not made for running in production on production?
And I was thinking how to do automatic restore from backup. This required me to know if
database is corrupted. And I can't find anything about this subject.
Read SQL documentation. Backusp, restores are all doe using standard SQL Commands. Totally easy to do that.
I want to make it very simple:
detect if database is corrupt (how?)
DBC Checkdb command. Can take a lot of time, though, depending on the database.
perhaps I don't know something about sql express, localdb, linq-to-sql.
This can be solved by reading the documentation. I would for example never use localdb on anything production.
Read the documentation? It starts with the first line:
Microsoft SQL Server 2014 Express LocalDB is an execution mode of SQL Server Express
targeted to program developers.

Related

Deploying entity framework code first with production database

I've developed a pretty simple web app using entity framework code first. I realized after hours of frustration that even though localdb is SQL Server Express it is actually not meant to be used with production when using 'publish' (the publish wizard). FYI I'm using EF 6.1.3, SQL Server 2014, VS 2013, and IIS 7.
If I understand correctly, when you click publish with localdb, all you're really doing is copying your localdb database to your IIS 7 server. I couldn't figure out why that when I updated my lodaldb database through VS migrations that my production server database wasn't being updated. I understand (and believe now) that it's actually two different instances of localdb, and hence not the same data.
OK whatever - I'm done with localdb and I created a real SQL Server 2014 db on my machine. I've googled for hours and can't figure out what to do now. I have some questions:
How do I manage this new database using EF? For instance, suppose I want to add a new column. First I add it to my localdb, do some testing, and do the migration using Add-Migration blah then Update-Database... Do I then have to generate a SQL script using VS and then manually run that on the production DB server?
I know this isn't great, but instead of using local DB with entity framework, can I just attach EF to a real staging SQL Server database (a test one) and skip all this localdb bull****? Then could I manage it using code-first migrations and keep everything in sync?
Am I supposed to use an Initializer? I've read conflicting reports about whether to use these or not for a production db (like this one)
public class PricedNotesInitializer: MigrateDatabaseToLatestVersion<...,...> {
}
It's frustrating that the only way I learn about this stuff is through blog posts from other people frustrated. I don't understand why the documentation is so garbage.
Thanks for your help and sorry for the rant.
Using an initializer
You can use the MigrateDatabaseToLatestVersion initializer so schema changes to the database will be (if possible without data loss) done automatically when your application first starts up after a deploy.
If data loss would occur you'll get an error and have to take appropriate action. This can be overriden to proceed even with data loss.
Development environment setup experience
As other answers already pointed out, you need one connection string per environment so the LocalDB is fine for development, I would even encourage it because it can be created and initialized (and seeded with test data) automatically for any new developer that needs to develop or debug it just by building and running the application from source.
The "set up new development environment" experience should be as smooth as possible with as few and preferably zero manual steps apart from loading the solution, building and running the code-base.
Automate your release cycle
Your deploy and release pipeline should be automatic and not require any manual commands that might be executed wrongly, be forgotten or worse.
What could be a manual step is a simple yes/no approval on the staged changes if you want to be careful or fulfill some compliance requirements.
Automated tests in your staging environment should however alleviate this and when successful automatically deploy to production - in a perfect world ;)
Running update-database manually against production requires that whatever machine is running it has access to the production database - an unlikely or not-recommended scenario if you're running it interactively I would say. If required you could script it as part of your automated deploy pipeline if you want more control over it than using the initializer, which seems best suited for simpler projects (which this one seemed to be though).
Thanks everyone for the help. I figured it out using your guys' help. For anyone interested in the steps, here they are. I'm just going to list some extra help here but the above answers truly answer the question. This assumes the set-up in my question. Once you have your database set-up, I would recommend you update it with your local db like so:
In VS2013, go to Tools -> sql server object explorer -> (LocalDb)\v11.0 -> databases -> [database_name] -> right click -> Data Comparison -> schema compare
In the right drop down, find your SQL database and test the connection to make sure it works.
Click compare -> Update Target (I wouldn't recommend this for production databases but if it's a staging db you just created, it's fine)
If you go SSMS (SQL Server Management Studio), you should see the new tables and whatever the schema compare tool made. Great!
If you want to use an initializer, go ahead, just make sure it's set to CreateDatabaseIfNotExists or something that won't drop the database. I mean I guess you could use anything you want, but it would defeat the purpose of the above steps.
Right click your web project, click publish, use web deploy, go to your databases, target your new database, ensure Execute Code First Migrations is checked (this will run all the migrations you've done for your localdb on your new database). You don't actually have to do this. You can alternatively leave this unchecked and do what Sampath recommends in the accepted answer.
Done! Now you've successfully converted to a real SQL Server Express DB.
To manage your database, just follow the answers above. Alternatively, use the publish wizard again, ensure Execute Code First Migrations is checked and publish!
You should have two connection strings, one for your localdb and one for your production SQL server.
You should develop as normal, for example using add-migration and update-database for your localdb.
Then when you are ready to publish to live should you change your connection string to your live one. Publish your site. Then run the update-database command. This will sync your live database to what you just published.
If you work on SQL express edition locally then you can migrate it pretty easily to the SQL production server.SQL production server can be a SQL Azure or your own production server.
A 1. You just need to change your local connection string to a production one and run below command on package manager. Then all your not updated migration scripts will run on the production.
PM> Update-Database
A 2 : I don't recommend this method.
A 3 : You can do that like this :
Database.SetInitializer(new CreateDatabaseIfNotExists<YourDbContext>());

Finished program. Proceeding to production and migrating from LocalDB

Until now all of my questions creating the program itself [C# Winforms] have been answered by searching the SO database. It's been an immense help really. But now i'm through with my program and I want to know what sort of procedure comes after; what is involved in the migration to an operating sql server.
I built my program with [Visual Studio 2013] to operate temporarily on a LocalDb for testing purposes. I noticed that nothing gets saved whenever I close the application, which actually saves alot of time during several test runs, but now I want it to save permanently on the published software system.
I've researched this topic abit and this is what i've come up with so far:
I would first setup the connectionstring to work with my sql server (MSSQLSERVEREXPRESS 2012/2014)
Publish my program. (For this I have prepared an install shield wizard. is this preferrable over a ClickOnce application?)
Run and prep the Sqlservice (No idea how to do this... I know, I know... but I'm really only fluent in the coding department)
Based on what I read, I would want to attach my database (.mdf service based database) through SQL management studio.
?? I'm not sure what happens after five.
Am I correct in these assumptions?
A) Would the program run just as simply as the LocalDb variant?
B) Would I finally be able to create permanent records?
C) Would the Sqlservice have to be ran each time, alongside the program?
D) What am I not seeing? What procedure am I missing?
All forms of help are appreciated. Do note that I have researched lightly about the topic, and have so far only come up with the idea to attach the Mdf to the server through SSManagementStudio and the rest is magic (so to speak).
Honestly, I know too little about sql server that I might not even be running on LocalDB, as I've read on another thread that I was merely working with Visual studio's SSData Tools (I've never consciously ran an SqlServer during the course of creating my program). But for the record, localDB is written on my connectionstring.
The problem has been [Resolved]!
FYI LocalDB is awesome and really isn't a hassle to deal with. I merely changed the COPY property below build options on the MDF file to Copy if Newer. Then I included everything I need into an InstallShield Wizard installer. Next problem came up was resolved by giving permission to use the MDF and LDF files to all users. I can now save permanent records. Thanks again Steve!

Suggestions on on-going development of database schema when it's under replication

I'm currently working on a database that comes with a legacy project which uses EntityFramework (updates code based on existing database using Data Model Designer)
Currently I work on the master copy and our developers work locally using SQL Server merge-replications on their local PC.
Issue here is that we recently started doing some change work that modifies the database schema, so when we use schema comparison (visual studio SQL compare feature), there are huge number of replication sp & schema changes that basically if I do update it will corrupt the live database. So my current solution is remove the dev server replication (so that the schema goes back to what it should look like without replication changes), then do the schema compare & update, and then create a new merge replication again so our developers can continue working on the dev db.
I thought it was just one-off db schema change, but just realized it will be continuous changes at least for the next 3-6 months, so that basically make each release a big headache (if it can be called as a 'release' prep...)
My SQL & EntityFramework knowledge is limited, can anyone shed some light on this for me please?
Thanks in advance!
Whats the observed need behind merge replication in the dev environment? I understand the need for devs to have a local copy they can mess with, run tests against etc, but I'm lost on why a full Publisher-Subscriber model is needed to synchronize DB state in a dev/test environment, and it seems to be causing you more problems than it may solve given the schema is going to be malleable for a few months.
If merge replication is not a hard requirement for the dev environment, I would suggest you replace it with an alternate method of distributing changes to the local copies. If the devs are working with a full copy of the DB anyway, I see no reason not to write a script that backs up the master copy on the dev server, then pulls that file down and restores it locally. Then, changes to that schema would be accomplished with change scripts, which can be run and tested locally before being applied to the master DB, then distributed on-demand with another run of the backup/restore script.
It's a slightly more manual process and an older way to work with DBs, but it seems far more palatable to me than breaking and re-establishing replication regularly. It'll require some collaboration to make sure devs aren't trying to make a backup at the same time or making conflicting changes to local copies that will blow up on the master copy; your devs ideally should be talking to each other anyway about this kind of thing, and you might make the script smart enough to look for a recent backup before generating another.
One more thought, don't know how feasible it is given your progress to date; it's not impossible to switch from DB-First to Code-First. The conversion is basically a hybrid process of Database First and Code First; the DB is reverse-engineered as a one-time operation to generate a model similar to DB First, but instead of EDMX files, the model is written out to source code files, and changes to those model files or to mapping conventions on the context can then be aggregated and applied to the schema as migrations in typical Code First style. Assuming you prepare the live DB for migrations as well (and have the live DB in the same state as the master Dev DB prior to the model generation), this even removes the requirement of a SQL compare and update; you just apply the migrations to the live DB, same as you would to any Dev instance. The only potential gotcha is that some migrations can be written destructively, so you have to make sure what you're about to apply isn't going to clear out all the fields in a renamed column.

Database Deployment Practices

I have deployed plenty of software to my clients. Mostly are Window Forms applications.
Here is my current practice.
Manually install SQLExpress and SQL Management Studio to each client PC.
Then use ClickOne to install the code from the server.
When there is a changes in code, I will use ClickOne to deploy -(NO PROBLEM with this step)
But when there is a change in a database column, what do I do?
I have even tried writing a database update script. Each time the program starts, it will read through the .sql update file and run them if the database exists. This solves the problem of updating the database columns, but it does not help in my DEBUGGING work when my customer complain there is a wrong data. At that point, I have to personally go to their site to check it out.
I find it difficult to have the database installed on the client PC as it make my debugging work very very difficult. I am thinking about moving my client database to a host on an Online server. But that then comes with these constraints:
What if the internet is down?
What if my customer has no internet?
Could you help to advise me? Is this a common problem faced by developer? What is the common practice out there? Does Window Azure or SQL CE help?
Depending on the data I would recommend using SQL CE.
If the data isn't too much, speed is not the primary goal (CE is slower than Express) and you don't need DB-Features not supported by CE (e.g. stored procedures) it is the better choice IMHO, because:
The client does not need to install a full SQL server (easier installation/deployment)
You do not have problems with multiple SQLExpress instances
Your SW doesn't need to worry if there even is a SQL instance
Less resources used on the client side
Additionally the clients could send you their SQL CE DB-File for inspection and you do not need to go to their site.
It is also relativly easy to implement an off site sync with SQL CE and MS Sync FW.
Installing one database per client PC can be tricky. I think you have a decent handle on how to deal with the issue currently. It seems like the real issue you are currently facing is debugging. To deal with this, there are a couple ways you could go:
Have the customer upload their copy of the database back to you. This would provide you with the data they have and you could use it with a debug copy of your code to identify the issues. The downside is that if the database is large it might be an issue transferring it.
Remote onto the customer's machine. Observe the system remotely using something like CoPilot. That way you could see what is happening in its natural environment.
There are probably other ways, but these are a couple of good ones. As for using an online database, this is an option but it brings its own set of issues with it. You mentioned a couple. As for Azure, that is cloud-based (online) so the same issues will apply. SQL CE won't help you any more than your current installation does.
Bottom line is that I would recommend you look into the ways to fix your one issue (as listed above) instead of creating a whole new set of issues by moving to an Internet-based solution. I would only recommend moving to the Internet if it was addressing a larger business need (for example, mobility). Doing the same thing you have been doing only online will probably just make life harder.
To recap the comments below since they are so pertinent to the issue, if you are choosing between file-based databases that don't need to be physically installed on the machine, your best choices are probably between SQLite and SQL CE. Microsoft supports SQL CE better but it is a larger package and has less features than the trim SQLite. Here is a good discussion on the differences:
https://stackoverflow.com/questions/2278104/sql-ce-sqlite-what-are-the-differences-between-them
However, the issue gets more complicated when you start looking at linq2sql since that is designed for SQL server. Microsoft does not support SQL CE with linq2sql out of the box, although there is a work-around that will get it to work:
http://pietschsoft.com/post/2009/01/Using-LINQ-to-SQL-with-SQL-Server-Compact-Edition.aspx
SQLite is not supported at all with linq2sql but there is a way to use linq to talk with SQLite:
LINQ with SQLite (linqtosql)
This library also supports other common databases including MySQL and Firebird.
You could use the SQLCMD utility to execute the change script, as mentioned in this related question

Best means to store data locally when offline

I am in the midst of writing a small program (more to experiment with vs 2010 than anything else)
Despite being an experiment it has some practical use for our local athletics club.
My thought was to access the DB (currently online) to download the current members and store locally on a laptop (this is a MS sql table, used to power the club's website).
Take the laptop to the event (yes there ARE places that don't have internet coverage), add members to that days race (also a row from a sql table (though no changes would be made to this), record results (new records in 3rd table)
Once home, showered and within internet access again, upload/edit the tables as per the race results/member changes etc.
So I was thinking I'd do something like write xml files locally with the data, including a field to indicate changes etc?
If anyone can point me in a direction I would appreciate it...hell if anyone could tell me if this has a name, I'd appreciate it.
Essentially what you need is, in addition to your remote data store, a local data store on your desktop. You could then write your code by hand to sync the data stores when you go offline / online, or you could use the Microsoft Sync framework to handle it for you.
I've personally used the Sync framework on a number of projects and once you get used to the conventions, it's pretty easy to use.
If a local storage format is what your after. SQLite is one option. You can copy your tables from the server to your local SQLite db.
You could also save your data to files, but XML is a horrible format for doing this. You'll probably want to use YAML or JSON instead.
You may want to take a look at SQL Server Compact -- it provides some decent capabilities with synchronizing back with the mothership SQL server.
If you're using MS SQL Server for production, and you only need to work offline on your personal computer, you could install MS SQL Server Express locally. The advantage here over using a different local datastore is that you can reuse your schema, stored procedures, etc. essentially only needing to change the connection string to your application (which you could run locally too through Visual Studio). You would have to write code to manually sync your online and offline db instances, but since it's a small application, it may be reasonable to just copy the entire database from production to local and then from local to production when you get home (assuming you're the only one updating the db, and wouldn't be potentially wiping out any new records entered in production while you were at the event).
Google Gears http://gears.google.com/ is intended if your app is a web app (which I didn't quite get what it is from your description)

Categories

Resources