{"id":73110,"date":"2016-05-23T15:19:10","date_gmt":"2016-05-23T15:19:10","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/uncategorized\/oracle-system-change-number-an-introduction\/"},"modified":"2026-03-18T00:59:45","modified_gmt":"2026-03-18T00:59:45","slug":"oracle-system-change-number-an-introduction","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/oracle-databases\/oracle-system-change-number-an-introduction\/","title":{"rendered":"Oracle SCN (System Change Number): How It Works"},"content":{"rendered":"<p>The Oracle System Change Number (SCN) is a logical, internal timestamp that Oracle uses to track every committed change to the database. Each time a transaction commits, Oracle assigns it a unique SCN &#8211; an ever-increasing number that establishes the exact ordering of all changes. Oracle uses the SCN to enforce read consistency (ensuring queries see a stable snapshot of data), to manage crash recovery (by comparing SCN values across control files, redo logs, and data file headers), and to coordinate operations like RMAN backups, Data Guard replication, and distributed transactions. Understanding SCN is essential for DBAs working with recovery scenarios, flashback queries, and database cloning.<\/p>\n<h2>Introduction<\/h2>\n<p>For many people working with Oracle database, SCN (System Change Number) is a topic that interests them greatly \u2013 but despite that it\u2019s a fascinating topic, it\u2019s confusing as well. In this article we will learn the nitty-gritty of SCN: what it is, where it is used, and how it works.<\/p>\n<p>It\u2019s worth mentioning that this is not and cannot be complete coverage of every detail about SCN. With that said, let\u2019s start.<\/p>\n<h2>SCN- Why do we need it?<\/h2>\n<p>Assume it\u2019s the end of the month and its payday. You are in the Payroll group and, with appropriate authority, have issued a query to pull the currently salary calculation of all the employees. Numbers are flowing across the screen, everything is going great.<\/p>\n<p>Suppose, while you are looking at the output, a colleague starts a new pay run and that batch job clears the current calculation summary. Things would certainly become confusing if your output suddenly showed \u20180\u2019 for the new rows coming out.<\/p>\n<p>Indeed, for this scenario, you would probably expect the output to reflect the \u2018state of the database\u2019 \u2013 the contents of each row \u2013 the way it existed at the moment you issued your query.<\/p>\n<p>One of the guarantees of the Oracle database is that \u201cthere are no dirty reads of user data\u201d. If necessary, Oracle will rebuild each row to the stable state at instant in time when the query was issued.<\/p>\n<p>Oracle does it nicely and very accurately through a \u201ctimer\u201d of its own, known as the System Change Number, AKA SCN.<\/p>\n<p>We will discuss these aspects of the SCN:<\/p>\n<ul>\n<li>The number itself<\/li>\n<li>The number generator<\/li>\n<li>Places where the number is stored<\/li>\n<\/ul>\n<p>So let\u2019s begin!<\/p>\n<h2>Building blocks for understanding SCN<\/h2>\n<p>In order to investigate SCN, several terms must be understood. Although these definitions are well documented, it is worth repeating them here:<\/p>\n<h3>Transaction<\/h3>\n<p>From the Concepts guide of Oracle online Documentation:<\/p>\n<blockquote>\n<p>\u201cA transaction is a logical, atomic unit of work that contains one or more SQL statements. A transaction groups SQL statements so that they are either all committed, which means they are applied to the database, or all rolled back, which means they are undone from the database. Oracle Database assigns every transaction a unique identifier called a transaction ID\u201d.<\/p>\n<\/blockquote>\n<p>More simply: when we start a transaction we initiate a set of changes. These must be either completed in totality or must not be completed at all. As the transactions occur in the database, the users reading any area that has changed must not be affected from any side effects which can alter their results. Find more information in the <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/oracle-databases\/a-guide-to-insert-update-and-delete-statements-in-oracle\/\"><span data-sheets-root=\"1\">Oracle INSERT, UPDATE, and DELETE guide<\/span><\/a>.<\/p>\n<p>In order for the transactions to be working correctly in any database, four <strong>ACID<\/strong> rules must be followed by the database. These are:<\/p>\n<ul>\n<li>Atomicity;<\/li>\n<li>Consistency;<\/li>\n<li>Isolation;<\/li>\n<li>Durability (To see how other systems manage this, you can explore <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/database-administration-sql-server\/understanding-the-sql-server-transaction-log\/\"><b data-path-to-node=\"4,3,0\" data-index-in-node=\"66\">SQL Server transaction log concepts<\/b><\/a>)<\/li>\n<\/ul>\n<p>So where does SCN fit in all of this? And the answer of that question is that using SCN only Oracle maintains data consistency. This is done to ensure that any point of time, there is no discrepancy in the results that are shown to the others when one user is changing something, and vice-versa.<\/p>\n<p>In order to summarize, in Oracle, the principle of \u201cReaders do not wait for writers and writers don\u2019t need for readers\u201d is completely and truly followed. In order to do so, it is of the utmost importance that the data, which is currently undergoing any sort of change, must not be available to anyone except the person who is making those changes. For transactions, this is required to maintain the integrity of the data. Three things can occur which can disrupt this integrity \u2013 Dirty Read, Fuzzy Read and Phantom Read. To ensure that there won\u2019t be any sort of integrity issues in these transactions, different levels of Isolations are available. These are:<\/p>\n<ul>\n<li>Read Uncommitted<\/li>\n<li>Read Committed<\/li>\n<li>Repeatable Read<\/li>\n<li>Serializable\u00a0<\/li>\n<\/ul>\n<h2>Transaction Isolation levels<\/h2>\n<p>From these, Oracle offers Read Committed as the <em>default<\/em> isolation level, making sure that there is no possibility of a user seeing the changes made by another user which are not yet committed. There must not be any read over that data which is marked as \u201cdirty\u201d and there must be a mechanism robust enough to make all this possible.<\/p>\n<p>To make this possible, SCN plays a vital role.<\/p>\n<h2>SCN, an Introduction<\/h2>\n<p>System Commit Number may be understood as Oracle\u2019s representation of time. Oracle uses SCN for controlling consistency, for performing recovery and to order the change vectors in the redo.<\/p>\n<p>The SCN is found in many locations \u2013 both in memory and on the disk. Different locations are used to help the database system identify various states of the database. For example, in some locations it is used to denote the transaction\u2019s completion status and whether it is active or committed.<\/p>\n<p>Contrary to popular belief, it does <strong>not<\/strong> get generated only at the time of commit, though that\u2019s what the name itself suggests. SCN is there all the time in the database, representing a time portion for the operation which is happening at that instant of time. It is not completely inaccurate to say that SCN doesn\u2019t get generated with a commit, it does \u2013 but that\u2019s not the sole way SCN is generated.<\/p>\n<p>The SCN is a two-part number that is generated on request, in response to an event. It is somewhat like the date and time derived from a calendar and clock combination; the clock changes quickly and only when it has gone through the complete 24 hour cycle is the overflow \u2013 the calendar \u2013 changed. However, the event that changes the clock is the \u2018pendulum\u2019 and is regular, whereas the event that changes the SCN is a call to one specific internal function.<\/p>\n<p>Similar to a calendar\/clock timestamp, the value may be recorded in a variety of different places, each for a different use.<\/p>\n<p>One real-world example similar to an SCN is an airport clock. Two people enter an airport at the same time and may note the clock time. That moment gives us \u2018an entry SCN\u2019 which happens to be the same for both people. One person gets a cart for baggage before checking in, whereas the other proceeds directly to the check-in counter. When the seats are assigned, each person may get a different \u2018check-in SCN\u2019 since the times are slightly different. A \u2018boarding SCN\u2019 may be assigned to indicate when each has boarded, but both get the same \u2018take-off SCN\u2019.<\/p>\n<p>Like the combination of calendar and clock, the SCN is guaranteed to be increasing under normal operation. There is no guarantee that the number will be sequential (missing numbers).<\/p>\n<p>So where is this information about SCN used in the Oracle database? Well, almost everywhere. Just like we associate Time with every activity of ours, SCN is also associated with every part of database\u2019s functionality. For example, when you try to select data from a table, SCN is used to confirm that whether that data is consistent or not. SCN is also found in the data block\u2019s Transaction Headers. This SCN would represent the time when the transaction started and when it was committed. Similarly, for each change performed, an entry in the redo log is maintained and for each of these entries, SCN is used to represent the time of transaction\u2019s occurrence.<\/p>\n<p>Read consistency uses SCN to decide how long it has to apply Undo over the dirty buffer so that the read consistent data request for a session can be completed. And as is well known, SCN is incremented with every commit operation.<\/p>\n<h3>SCN Format and Structure<\/h3>\n<p>SCN is a huge number with two components to it: SCN Base &amp; SCB Wrap.<\/p>\n<p>SCN is a 6 byte (48 bits) number. Out of these 48 bits, SCN_WRAP is a 16 bit (2 Bytes) number and SCN_BASE is a 32 bit (4 Bytes) number. Both BASE &amp; WRAP are used to control the SCN\u2019s increment and to ensure that the database won\u2019t run out of it. SCN_WRAP is incremented by 1 when SCN_BASE reaches the value of 4 Billion and SCN_BASE becomes 0.<\/p>\n<p>From Oracle Version 12c, the SCN number is an 8 byte number.<\/p>\n<p>So how do we see the current SCN value? The easiest way is to query the view V$DATABASE. Have a look:<\/p>\n<pre>SQL&gt; select current_scn from V$database;\n\nCURRENT_SCN\n-----------\n    1123790<\/pre>\n<p>As we can see, that SCN is displayed as a number. This is good because it makes the use of SCN easy for us in our statements performing recovery, flashback, etc. If we want, we can convert SCN to a Hexadecimal value as well:<\/p>\n<pre>SQL&gt; select to_char('1123790','xxxxxxxx') scn_hex from dual;\n\nSCN_HEX\n---------\n   1125ce<\/pre>\n<p>Here is an example of the output from the same view accessed couple of times:<\/p>\n<pre>SQL&gt; select current_scn from V$database;\n\nCURRENT_SCN\n-----------\n    1178883\n\nSQL&gt; \/\n\nCURRENT_SCN\n-----------\n    1178885\n\nSQL&gt; \/\n\nCURRENT_SCN\n-----------\n    1178886<\/pre>\n<p>Interestingly, this increase in the SCN value shows an important aspect of SCN. We can see that with each execution, there is an increase in the count of the SCN. By querying the view V$DATABASE, we are actually causing the jump in the SCN number.<\/p>\n<h3>SMON_SCN_TIME Table<\/h3>\n<p>The easiest way to see both of these values is from an internal table owned by SYS user- SMON_SCN_TIME. The following is an output from the same (11204).<\/p>\n<pre>SQL&gt; select SCN_wrp, SCN_bas, SCN from smon_SCN_time where rownum &lt; 3;\n\n   SCN_WRP    SCN_BAS\t     SCN\n---------- ---------- ----------\n\t 0     998222\t  998222\n\t 0     998406\t  998406<\/pre>\n<p>This table contains the entries of the SCNs generated. It stores the data in roughly 5-minute increments and holds 5 days\u2019 worth of data. This means the table contains approximately 1440 records. The exact number of records will vary slightly since the storage increment is not exactly 5 minutes.<\/p>\n<pre>SQL&gt; select count(*) from SMON_SCN_TIME;\n\n  COUNT(*)\n----------\n      1494<\/pre>\n<p>In versions of Oracle prior to 10g, the time mapping of SCN with time was +\/- 5 minutes but from 10g onwards, this is changed to +\/- 3 seconds. As this is stores in an internal table, Oracle doesn\u2019t allow access to the information from this table directly. To access it, APIs are provided. One such API is from the package DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER, which can be used to access the sequence number from this table. An example of this is given below (thanks to Tom Kyte for the query):<\/p>\n<pre>SQL&gt; l\n\t select SCN_to_timestamp(SCN) ts, min(SCN), max(SCN)\n\t       from (\n\t    select dbms_flashback.get_system_change_number()-level SCN\n\t      from dual\n\t     connect by level &lt;= 100\n\t\t   )\n\t      group by SCN_to_timestamp(SCN)\n*\t   order by SCN_to_timestamp(SCN)\nSQL&gt; \/\n\nTS\t\t\t\t\t\t\t\t\t      MIN(SCN)\t MAX(SCN)\n--------------------------------------------------------------------------- ---------- ----------\n06-MAY-16 05.22.04.000000000 PM \t\t\t\t\t       1245323\t  1245323\n06-MAY-16 05.22.07.000000000 PM \t\t\t\t\t       1245324\t  1245324\n06-MAY-16 05.22.10.000000000 PM \t\t\t\t\t       1245325\t  1245325\n06-MAY-16 05.22.13.000000000 PM \t\t\t\t\t       1245326\t  1245326\n06-MAY-16 05.22.16.000000000 PM \t\t\t\t\t       1245327\t  1245327\n06-MAY-16 05.22.19.000000000 PM \t\t\t\t\t       1245328\t  1245328\n06-MAY-16 05.22.22.000000000 PM \t\t\t\t\t       1245329\t  1245329\n06-MAY-16 05.22.25.000000000 PM \t\t\t\t\t       1245330\t  1245330\n06-MAY-16 05.22.28.000000000 PM \t\t\t\t\t       1245331\t  1245331\n06-MAY-16 05.22.31.000000000 PM \t\t\t\t\t       1245332\t  1245332\n06-MAY-16 05.22.34.000000000 PM \t\t\t\t\t       1245333\t  1245333\n06-MAY-16 05.22.37.000000000 PM \t\t\t\t\t       1245334\t  1245334\n06-MAY-16 05.22.40.000000000 PM \t\t\t\t\t       1245335\t  1245335\n06-MAY-16 05.22.43.000000000 PM \t\t\t\t\t       1245336\t  1245336\n06-MAY-16 05.22.46.000000000 PM \t\t\t\t\t       1245337\t  1245337\n06-MAY-16 05.22.49.000000000 PM \t\t\t\t\t       1245338\t  1245338\n06-MAY-16 05.22.52.000000000 PM \t\t\t\t\t       1245339\t  1245339<\/pre>\n<h3><strong>How can we map SCN with Timestamp in versions prior to 10g?<\/strong><\/h3>\n<p>It\u2019s important to remember that this table doesn\u2019t show <em>why<\/em> there would be any increase in the rate of increase in the SCN numbers. With a little formatting, it is possible to have an idea of the SCN numbers generated but the source of their growth won\u2019t be evident from this table.<\/p>\n<p>Another way to check this is from the view V$LOG_HISTORY. The view contains the SCN in the form of the columns FIRST_CHANGE# and NEXT_CHANGE# and we can see through these two columns the amount of SCNs generated in the database over a period of time. The \u201cfirst_change# is the lowest SCN that appears in the archived log file at a given sequence number of this thread. The \u201cnext_change#\u201d is the lowest SCN that appears in the next archived log file.<\/p>\n<pre>SQL&gt; select thread#, first_change#,next_change# from V$log_history;\n\n   THREAD# FIRST_CHANGE# NEXT_CHANGE#\n---------- ------------- ------------\n\t 1\t  925702       958823\n\t 1\t  958823       959634\n\t 1\t  959634       972579\n\t 1\t  972579       993714\n\t 1\t  993714      1020785\n\t 1\t 1020785      1023738\n\t 1\t 1023738      1023873\n\t 1\t 1023873      1023995<\/pre>\n<p>As with SMON_SCN_TABLE it\u2019s not possible to find the source of the increase in the generation of the SCN numbers from this table view. Still, you can use this view in the single instance as well as in an RAC environment.<\/p>\n<h3><strong>SCN Increases Using a Sequence?<\/strong><\/h3>\n<p>By now it should be pretty evident that SCN appears to be a number that\u2019s constantly increasing. Interestingly, even though it\u2019s a number, Oracle doesn\u2019t use any sequence to increase it but uses internal functions instead. For example, to increase the SCN_BASE, the function used internally is KCMGAS(Get and Advance SCN). This function is called each time a new SCN is requested and the call for this function is increased. Similarly to this function, KCMGCS (Get Current SCN) is used to get the current SCN and the call used for it. These function calls can be seen from the V$sysstat view. A description of these statistics can be found in the <a href=\"https:\/\/docs.oracle.com\/database\/121\/REFRN\/GUID-2FBC1B7E-9123-41DD-8178-96176260A639.htm\">12.1 Reference guide<\/a>.<\/p>\n<p>Let\u2019s see how these calls link with the SCN generation. We are using two sessions here \u2013 one to see the calls in the view V$SYSSTAT view, and the other session to pull the SCN.<\/p>\n<pre>Session -1 \nSQL&gt; l\n  1* select current_SCN from V$database\nSQL&gt; \/\n\nCURRENT_SCN\n-----------\n     698815\n\nSQL&gt;<\/pre>\n<p>For this SCN, these were the values for V$sysstat:<\/p>\n<pre> SQL&gt; l\n  1  select name,value from V$sysstat\n  2* where name like '%calls to%'\nSQL&gt; \/\n\nNAME                                                                  VALUE\n---------------------------------------------------------------- ----------\ncalls to kcmgcs                                                         427\ncalls to kcmgrs                                                           0\ncalls to kcmgas                                                        7272\ncalls to get snapshot SCN: kcmgss                                    159790\n\nSQL&gt;<\/pre>\n<p>Let\u2019s issue a query to see the current SCN in session 1:<\/p>\n<pre>SQL&gt; l\n  1* select current_SCN from V$database\nSQL&gt; \/\n\nCURRENT_SCN\n-----------\n     698815\n\nSQL&gt; \/\n\nCURRENT_SCN\n-----------\n     698889\n\nSQL&gt;<\/pre>\n<p>And here is the result of the second session 2:<\/p>\n<pre>SQL&gt; \/\n\nNAME                                                                  VALUE\n---------------------------------------------------------------- ----------\ncalls to kcmgcs                                                         427\ncalls to kcmgrs                                                           0\ncalls to kcmgas                                                        7272\ncalls to get snapshot SCN: kcmgss                                    159790\n\nSQL&gt; \/\n\nNAME                                                                  VALUE\n---------------------------------------------------------------- ----------\ncalls to kcmgcs                                                         427\ncalls to kcmgrs                                                           0\ncalls to kcmgas                                                        7278\ncalls to get snapshot SCN: kcmgss                                    159905\n\nSQL&gt;<\/pre>\n<p>We can see that the calls to the KCMGAS has increased to 7278 from the last value, 7272. As Oracle doesn\u2019t use a sequence to increase the number, there is no guarantee that the SCN number will always be increased in the same order.<\/p>\n<h2>Conclusion<\/h2>\n<p>In this article, we have had a look at what the SCN is, how to view it and what the requirements for it are. In the next article, we will see what different types of SCNs are available and how they are used in the database. Stay tuned!<br \/><strong>Read also:<\/strong> <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/oracle-databases\/convert-single-instance-to-rac-part-2-manually-convert-to-rac\/\">Converting single instance to Oracle RAC<\/a><\/p>\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>FAQs: The Oracle System Change Number (SCN)<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. What is Oracle SCN and why is it important?<\/h3>\n            <div class=\"faq-answer\">\n                <p>The Oracle System Change Number (SCN) is a logical clock that assigns a unique, ever-increasing number to each committed transaction. It\u2019s the foundation of Oracle\u2019s read consistency model &#8211; when you run a query, Oracle uses the SCN to reconstruct each row to its state at the moment your query began, ensuring you never see uncommitted (\u201cdirty\u201d) data. SCN is also critical for crash recovery, RMAN backups, and Data Guard synchronization.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. Where is the SCN stored in Oracle?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Oracle stores SCN values in multiple locations: the control file (which tracks the current database SCN), every redo log record (which includes the SCN of the change), data file headers (which record the last checkpoint SCN), and the data blocks themselves (which track the SCN of the last modification). During recovery, Oracle compares these SCN values to determine which changes need to be replayed.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. How do you check the current SCN in Oracle?<\/h3>\n            <div class=\"faq-answer\">\n                <p>You can query the current SCN using SELECT CURRENT_SCN FROM V$DATABASE or SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL. The V$DATABASE view shows the database-level SCN, while the DBMS_FLASHBACK function returns the current system SCN. These are useful for flashback operations, backup validation, and troubleshooting replication lag.<\/p>\n            <\/div>\n            <\/section>\n","protected":false},"excerpt":{"rendered":"<p>Learn how Oracle&#8217;s System Change Number (SCN) maintains read consistency and data integrity. Covers SCN structure, where it&#8217;s stored (control files, redo logs, data file headers), and how Oracle uses it to track transactions and recover databases.&hellip;<\/p>\n","protected":false},"author":316201,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143533],"tags":[48495,48523],"coauthors":[48556],"class_list":["post-73110","post","type-post","status-publish","format-standard","hentry","category-oracle-databases","tag-scn","tag-system-change-number"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/316201"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=73110"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73110\/revisions"}],"predecessor-version":[{"id":109288,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73110\/revisions\/109288"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=73110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=73110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=73110"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=73110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}