when exactly does writing in data files occur in sql? - sql

i am currently studying transaction management in dbms .... from database systems elmasri and navathe 6th edition link: http://mathcomp.uokufa.edu.iq/staff/kbs/file/2/Fundamentals%20of%20Database%20Systems%20-%20Ramez%20Elmasri%20&%20Navathe.pdf
can someone please tell (in short) the transaction commit process i.e. without going into too much detail .... i also read some portion from oracle forum link :
https://docs.oracle.com/cd/B19306_01/server.102/b14220/transact.htm
what i could understand is that actual writing can take place before or after committing ... but if changes made have to be visible to all users then it must take before commit not after commit , right ?
can someone please help me clear the confusion ??

As the forum post indicates, writes to the data files are completely independent of transaction control. Changes might be written before a transaction commits, they might be written after the transaction commits.
When changes are made, those changes are made to a version of the data in memory. In order for a transaction to commit successfully (assuming default commit settings), the change must be written to the redo logs. That allows the database to re-create the change if it has not been written to data files and the database crashes. Conversely, if a change is written to a data file before the transaction is committed, information on how to reverse the change will be in the undo logs so that if the transaction will be able to be rolled back if the database fails before the transaction commits (or if the application issues a rollback).

Related

Inserted data is not shown in Oracle db using a direct query

I was not able to find a solution for this question online, so I hope I can find help here.
I've inherited a Java web application that performs changes to an Oracle database and displays data from it. The application uses a 'pamsdb' user ID. The application inserted a new row in the one of the tables (TTECHNOLOGY). When the application later queries the db, the result set includes the new row (I can see it in print outs and in the application screens).
However, when I query the database directly using sqldeveloper (using the same user id 'pamsdb'), I do not see the new row in the modified table.
A couple of notes:
1) I read here and in other locations that all INSERT operations should be followed by a COMMIT, otherwise other users cannot see the changes. The Java application does not do COMMIT, which I thought could be the source of the problem, but since I'm using the same user ID in sqldeveloper, I'm surprised I can't see the changes there.
2) I tried doing COMMIT WORK from sqldeveloper, but it didn't change my situation.
Can anyone suggest what's causing the discrepancy and how can it be resolved?
Thanks in advance!
You're using the same user, but in a different session. Once session can't see uncommitted changes made in another session, for any user - they are independent.
You have to commit from the session that did the insert - i.e. your Java code has to commit for its changes to be visible anywhere else. You can't make the Java session's changes commit from elsewhere, and committing from SQL Developer - even as the same user - only commits any changes made in that session.
You can read more about connections and sessions, and transactions, and the commit documentation summarises as:
Use the COMMIT statement to end your current transaction and make permanent all changes performed in the transaction. A transaction is a sequence of SQL statements that Oracle Database treats as a single unit. This statement also erases all savepoints in the transaction and releases transaction locks.
Until you commit a transaction:
You can see any changes you have made during the transaction by querying the modified tables, but other users cannot see the changes. After you commit the transaction, the changes are visible to other users' statements that execute after the commit.
You can roll back (undo) any changes made during the transaction with the ROLLBACK statement (see ROLLBACK).
The "other users cannot see the changes" really means other user sessions.
If the changes are being committed and are visible from a new session via your Java code (after the web application and/or its connection pool have been restarted), but are still not visible from SQL Developer; or changes made directly in SQL Developer (and committed there) are not visible to the Java session - then the changes are being made either in different databases, or in different schemas for the same database, or (less likely) are being hidden by VPD. That should be obvious from the connection settings being used by the two sessions.
From comments it seems that was the issue here, with the Java web application and SQL Developer accessing different schemas which both had the same tables.

What happens when a transaction is being carried out during backing up of LDF files?

My DB Admin advised that I should regularly take backup of .ldf files. Fine, this SQL post here explains this beautifully.
Consider that a transaction is being done in SQL Server. And at the same time, a scheduled process tries to access the .ldf file for backing it up.
What happens ? How this works ?
You must read Article Understanding SQL Server backup by Paul Randal. That is the best I can see which is available and can explain you in details various aspects.
Coming to your question a transaction log backup includes all information from previous transaction log back or full backup that started the log chain. Backup simply means reading information froma file(data or log) and writing it to destination disk. The transaction any would work independed of log backup running. A transaction follow a WAL(write ahead logging) protocol, for practical purposes all transaction information is first written in log file and then changes are later made to data file. So when transaction is running it would not be affected by transaction log backup job which is running both are doing different task and are muttually exclusive events. Current backup would try to backup all logs which are marked as committed and would truncate the logs if no transaction requires it. If any portion of log is committed after log backup has read that portion it would not come in current log backup but would come under further log backup.
Transacion log backup has important role in crash recovery it helps in determining what all operations has to be roll forwared and what has to be rolled back. Without transaction log backup or transaction log crash recovery is not possible
You must also read Logging and recovery in SQL Server to know about life cycle of a transaction.
The excat answer as to what acctual steps happens inside is beyond scope of discussion as nobody can exactly tell you what would happen but reading the article would give you a good idea.
Please let me know if you have any further questions.

How isolation level "READ COMMITED" is working in the Oracle DB?

i am interesting to know know how the isolation level"READ COMMITTED" is provided in Oracle DB implementation. I already know that DB makes records in REDO log, but for now i think that that REDO log is only used to repeat the transaction in case when some unpredictable crash will happen during the transaction. Also i know that DBWR writes the "dirty blocks" every time the REDO log file is filled. But my question is: if DBWR writes "dirty"(changed blocks) to the disk, how isolation level"READ COMMITTED" is provided. I mean during writing DBWR writes data directly to data files or in some special "place" on disk that is visible from current transaction and invisible from other transaction? So after the COMMIT this "place" becomes visible and that's all ? How this works in reality? Sorry for bad English.
In addition to the REDO log, you also have the UNDO tablespace.
When updating data, the old value is stored in the UNDO tablespace. When Oracle sees that you would be reading uncommitted data for a record, it reconstructs the old value from there.
UNDO is also used during database recovery: In addition to re-applying writes that have been committed but not made it to the database files before the crash, the opposite can also take place: rolling back uncommitted changes to database files that happened before the crash.

How do I undo an update statement I made to a database

It's a test environment, I needed some data to test an Update query, but accidentally updated a column in all rows to have wrong data. Must I use a backup to restore the data back to the previous instance, or is there some secret with transaction log that I can take advantage of?
Thanks in advance.
There is a non-secret transaction log called transaction log that you can recover from to a point in time. Here's how... That annoying little file with the ldf extension is the transaction log, as opposed to the .mdf file that is your normal db data.
Unless you have truncated the transaction log (ldf) or otherwise mucked with it, you should be able to do exactly the kind of restore (undo) that you're looking for.
If your database was in full recovery mode then you can try reading transaction log using third party tool such as this one or you can try doing this yourself with DBCC LOG command.
If db is in full recovery then a lot of data is stored in transaction log but it’s not easily readable because MS never polished official documentation for this and because it’s purpose is not recovery but making sure transaction is committed correctly.
However there are workarounds to reading it like using the tool above (paid tool unfortunately but has a trial) or decoding the results of DBCC LOG yourself.
Not unless you wrapped your sql in a transaction block - begin transaction, rollback, commit. That one of the dangerous things about sql server. With Oracle you have to physically commit each transaction which is much safer imho.

How to rollback a database deployment without losing new data?

My company uses virtual machines for our web/app servers. This allows for very easy rollbacks of a deployment if something goes wrong. However, if an app server deployment also requires a database deployment and we have to rollback I'm kind of at a loss. How can you rollback database schema changes without losing data? The only thing that I can think of is to write a script that will drop/revert tables/columns back to their original state. Is this really the best way?
But if you do drop columns then you will lose data since those columns/tables (supposedly) will contain some data. And since I'd assume that any rollbacks often are temporary in that a bug is found, a rollback is made to get it going while that's fixed and then more or less the same changes are re-installed, the users could get quite upset if you lost that data and they had to re-enter it when the system was fixed.
I'd suggest that you should only allow additions of tables and columns, no alterations or deletions, then you can rollback just the code and leave the data as is, if you have a lot of rollbacks you might end up with some unused columns, but that shouldn't happen that often that someone added a table/column by mistake and in that case the DBA can remove them manually.
Generally speaking you can not do this.
However assuming that such a rollback makes sense it implies that the data you are trying to retain is independent from the schema changes you'd like to revert.
One way to deal with it would be to:
backup only data (script),
revert the schema to the old one and
restore the data
The above would work well if schema changes would not invalidate the created script (for example changing number of columns would be tricky).
This question has details on tools available in MS SQL for generating scripts.