Get all database actions (insert, update , delete, alter, ...)information - sql-server-2008

in sql server 2008 is there a way to get the user that inserted some rows, or updated, deleted, dropped, altered some tables?
can we get this information the date that occurred?
also is there a way to know if the data was inserted from the same machine or from other machine?
Edit: if it's really hard then maybe a way to achieve this is to user triggers
but is there a way to catch every action that happens on the DB so i can log them all??
something like on insert on any table
i want everything to be done on the DB so no matter what business app i use it will be logged

Unless you already had something set up in advance - a CDC mechanism of some kind it is going to be incredibly difficult to extract that information from the logs. It is possible given enough time, but it is a highly skilled forensic activity that is extremely time consuming to perform. (And relies on full logs being available.) There are third party log readers than can help with this but it will still be a huge effort.

Related

MySQL - What happens when multiple queries hit the database

I am working on a project, which will be used by around 500 employees in my organization. Currently, it's still in development phase, and very few people(around 10) are using it. I'm using MySQL. I just want to know, what happens if many users are doing front end edits and then save, at the same point of time? Some SELECT queries that I've written do take as long as 6 seconds to execute. As only one query can be executed at any point of time, if already a query is in progress, and another hits the database, will it create problem? If this is a common situation in large scale projects, please let me know how can I handle this. I'm not sure, if I've made myself clear :). Any advice or links will be very helpful.
From technical aspect, no - nothing bad will happen, the database won't go ballistics and die on you, they're made for purposes like concurrent access.
From logical point of view - something bad will happen. If two people edit the same thing at the same time and then post it at the same time - it gets saved to hard drive one after another. The last one to save is the one whose updates will be on the HDD, effectively causing the first person to lose their changes.
You can approach this problem from several angles. Some projects introduce the concept of locking (not table locking but in-app locking). It revolves around marking a record as locked using a boolean column and if anyone tries to access that record for updating, the software says that someone else is editing it. It's something really difficult to implement and for the most time it doesn't work as expected (I think I vaguely remember Joomla! using something like that, it was one of the most annoying features ever).
The other option you have is to save each update as a revision. That way you can keep track on who updated what and when and you never lose any records in case of would-get overwritten. I believe that SO and Wikipedia use that approach and it works really great because you can inspect what two or more people have done and merge their contributions.
Optimistic Concurrency Control
http://en.wikipedia.org/wiki/Optimistic_concurrency_control
Make sure that each record contains date metadata on last changed/modified time, and load that as part of your data object. Then when attempting to commit the row to database, check the last_modified time in the table to ensure that it is the SAME as the one stored in memory for your object. If it matches, commit it, else throw exception.

MySQL: Create a user for reading and another for writing?

I have been searching for this for a while and unable to find something useful.
Is it a good practice or even important to create 2 MySQL users, one for reading and then use that whenever I'm initiating a MySQL SELECT.
And on the other side, create another user for writing and use it whenever I'm doing an INSERT, UPDATE, DELETE, ...?
Would this help at anything for example if I'm writing and reading to the database at the same time?
Assume we're using InnoDB tables.
"good practice" is very hard to define - you've got a whole bunch of different things to trade off against each other.
I'm assuming that the database is being used as a back-end for some other system, and that your users don't have direct access to a SQL prompt. In that case, there are no real benefits to creating different MySQL users - it simply makes the front-end more complex, and an attacker who can reach the database and knows the "read-only" credentials almost certainly also knows the "read/write" credentials. From a security point of view, you should invest your time in network security of the database server, and secure storage of connection details.
From a concurrency point of view - two or more users reading and writing at the same time - you won't really gain anything either. This particular requirement is one of the things relational databases do very well, and I don't think it's affected at all by the permissions of the users - it's far more to do with whether you're using transactions, and how quickly your SQL executes.

How to recover just deleted rows in mysql?

Is it possible to restore table to last time with data if all data was deleted accidentally.
There is another solution, if you have binary logs active on your server you can use mysqlbinlog
generate a sql file with it
mysqlbinlog binary_log_file > query_log.sql
then search for your missing rows.
If you don't have it active, no other solution. Make backups next time.
Sort of. Using phpMyAdmin I just deleted one row too many. But I caught it before I proceeded and had most of the data from the delete confirmation message. I was able to rebuild the record. But the confirmation message truncated some of a text comment.
Someone more knowledgeable than I regarding phpMyAdmin may know of a setting so that you can get a more complete echo of the delete confirmation message. With a complete delete message available, if you slow down and catch your error, you can restore the whole record.
(PS This app also sends an email of the submission that creates the record. If the client has a copy, I will be able to restore the record completely)
As Mitch mentioned, backing data up is the best method.
However, it maybe possible to extract the lost data partially depending on the situation or DB server used. For most part, you are out of luck if you don't have any backup.
I'm sorry, bu it's not posible, unless you made a backup file earlier.
EDIT: Actually it is possible, but it gets very tricky and you shouldn't think about it if data wasn't really, really important. You see: when data get's deleted from a computer it still remains in the same place on the disk, only its sectors are marked as empty. So data remains intact, except if it gets overwritten by new data. There are several programs designed for this purpose and there are companies who specialize in data recovery, though they are rather expensive.
For InnoDB tables, Percona has a recovery tool which may help. It is far from fail-safe or perfect, and how fast you stopped your MySQL server after the accidental deletes has a major impact. If you're quick enough, changes are you can recover quite a bit of data, but recovering all data is nigh impossible.
Of cours, proper daily backups, binlogs, and possibly a replication slave (which won't help for accidental deletes but does help in case of hardware failure) are the way to go, but this tool could enable you to save as much data as possible when you did not have those yet.
No this is not possible. The only solution will be to have regular backups. This is very important.
Unfortunately, no. If you were running the server in default config, go get your backups (you have backups, right?) - generally, a database doesn't keep previous versions of your data, or a revision of changes: only the current state.
(Alternately, if you have deleted the data through a custom frontend, it is quite possible that the frontend doesn't actually issue a DELETE: many tables have a is_deleted field or similar, and this is simply toggled by the frontend. Note that this is a "soft delete" implemented in the frontend app - the data is not actually deleted in such cases; if you actually issued a DELETE, TRUNCATE or a similar SQL command, this is not applicable.)
If you use MyISAM tables, then you can recover any data you deleted, just
open file: mysql/data/[your_db]/[your_table].MYD
with any text editor

Granular 'Up to the minute' data recoverability of mySQL database data

I operate a web-based online game with a mySQL backend. Every day many writes are performed against hundreds of related tables holding user data.
Frequently a user's account will become compromised. I would like the ability to restore the user's data to a certain point in time prior to the attack without affecting any other user data.
I'm aware of binary logging in mySQL, but as far as I know this is whole-database recovery up to a certain point in time. I would like a more granular solution, ie able to specify which tables, which rows etc.
What should I be looking into? What are the general best-practices?
If you create and use audit tables (populated through triggers) you can always get back to the data for one particular user in any table.
Be sure to write your general restore script before you need it though. Much easier to put in a userid into a script that you already have available than to sit there looking at the audit tables going, how do I do this again.
MySQL (or any other RDBMS that I'm aware of) is not able to do that by itself. Therefore you should implement that yourself in your application layer.
This is (without external modules) not possible.
As thejh in the comments suggested, revisions would be a good solution. When you only need to work with userdata, create a table that resembles the usertable with additional timestamp or similar and run a cron job once a week/day/.. that copies the userdata that has recently been modified (additional flags/dates in the actual user table) into this table.

SQL Server 2008 Mirrored DB Update Rollback - Crisis

I am a programmer who has done a very bad thing and somehow didn't select the WHERE clause before hitting F5 on an update query in SQL Server 2008.
I know this isn't a programming question but it is a question from a desprate programmer ...
Is there anyway to get the one column's data back from the transaction log or a log kept by the mirroring system?
Oh and yes, it gets better: the nightly maintenance plan for backups seems to have been turned off.
Any ideas please?
-Mike
stunned at reading "(197875 row(s) affected)"
Call off the dogs. I regenerated the database from an old backup and the source log files used to populate it.
In a more lucid moment I came to understand my question as:
Is the original value of a row stored in the transaction log of an update operation?
I'm almost sure the answer is no.
Thanks for listening.
-Mike
Mike, glad to hear you were able to recover the data. Now is the time to implement some sort of backup strategy :)
To your question, the transaction log can be backed up (every 10 minutes, etc.), but no... the original value is not persisted anywhere unless you explicitly build that functionality in. A great place to start is Ola Hallengren's great set of free maintenance scripts.