Braveheart
Programmer
TIP: Understanding why the identity field sometimes jumps massively (I've seen 30 quadrillion)<br>
<br>
Background: What is the identity burning set factor? <br>
<br>
The identity burning set factor configuration parameter is a percentage in decimal form x 10 million.<br>
<br>
The default value, 5000, represents .05%, or .0005.<br>
<br>
When an identity column is defined in a table, the server automatically assigns a unique sequential number for that identity column during inserts. To avoid excessive I/O, Adaptive Server Enterprise keeps blocks of numbers available in memoryfor use in identity values and keeps track of the current pointer in that block in memory.<br>
<br>
The number of values in the block is controlled by the identity burning set factor. The identity column is a numeric datatype with a pre-defined precision. The server uses the possible range of values to determine which numbers are reserved.<br>
<br>
For example, an identity column, "colA," is defined as numeric(7,0). The values of this column range from 1 to 9,999,999. Using the default burning set factor of 5000, .05% of the values are made available at a time. Therefore, the size of a block of numbers reserved in memory is .0005 (or .05%) x (9,999,999 +1) = 5000 values.<br>
<br>
If the server shuts down unexpectedly, all unused numbers in the current reserved block (in memory) are lost. When the server restarts, the next insert starts with the next block. Therefore, abnormal shutdowns can cause large gaps in the identity column. An orderly shutdown (normal) does not delete identity values.<br>
<br>
Note: <br>
A shutdown with nowait is an unexpected shutdown and<br>
causes the block of numbers to be lost. For more<br>
information, see the Adaptive Server Enterprise System<br>
Administration Guide, the Transact-SQL User's Guide,<br>
and the Adaptive Server Enterprise Reference Guide.<br>
<br>
<br>
Example: How Adaptive Server "loses" block values<br>
<br>
In this example, we use the above identity column, colA, and perform a shutdown with nowait: <br>
<br>
1.After 5 inserts into the table we have: <br>
<br>
colA<br>
-------<br>
1<br>
2<br>
3<br>
4<br>
5<br>
<br>
<br>
2.We now shut down the server with nowait, then re-start the server. <br>
<br>
select colA from table: <br>
<br>
colA<br>
-------<br>
1<br>
2<br>
3<br>
4<br>
5<br>
<br>
3.We perform an insert into the table, then select colA again:<br>
<br>
colA<br>
-------<br>
1<br>
2<br>
3<br>
4<br>
5<br>
5002<br>
<br>
4.If we perform a shutdown with nowait again, then repeat the insert and select colA again, colA displays as<br>
follows:<br>
<br>
colA<br>
-------<br>
1<br>
2<br>
3<br>
4<br>
5<br>
5002<br>
10003<br>
<br>
<br>
Note: <br>
The starting value in the next block almost always will not<br>
be the first value in the new block. This is because of a<br>
current value that is stored in the dbtable info. When the<br>
block is lost, the server goes to the next block and the next<br>
value in the dbtable info. In the above case, the last value in<br>
the dbtable was 1.<br>
<br>
<br>
Correcting identity column gaps <br>
<br>
You can fix the rows containing the large numbers to correct gaps in the identity column. Perform the following steps:<br>
<br>
1.Turn on identity_insert.<br>
<br>
1> set identity_insert table_name on<br>
<br>
2> go<br>
<br>
2.Record the row(s) information. Because you cannot update an identity column, you must delete the row(s) and insert them again with the correct identity values.<br>
<br>
3.Correct all rows in error.<br>
<br>
4.bcp out the data from the table.<br>
<br>
5.Turn off identity_insert.<br>
<br>
1> set identity_insert table_name off<br>
<br>
2> go<br>
<br>
6.Drop the table and re-create it. This step resets the identity column's auto-start number to 1. <br>
<br>
7.bcp the data back into the table using the -E option to maintain the identity values that appear in the host file. <br>
<br>
Note: <br>
The -E option tells the server not to use the auto-insert<br>
identity numbers and to use the identity numbers included<br>
in the bcp data.<br>
<br>
<br>
The next identity number should be one greater than the largest identity number in the table. <br>
<br>
<br>
Understanding the identity grab size<br>
<br>
The identity grab size parameter allows a server process to reserve a block of identity column values for inserts into tables with identity columns.<br>
<br>
What this means is that a particular server process gets its own block of numbers to use. This is useful if a particular server process needs to insert contiguous identity values. Identity grab size is a server-wide parameter, so do not set it to a high value. Set identity grab size only to a value large enough to accommodate the largest group of records you want to insert into contiguous rows. The default is 1. <br>
<br>
Troubleshooting the identity burning set factor<br>
<br>
In this example, performing shutdown with nowait confuses the user into believing that the identity burning set factor did not re-set.<br>
<br>
0800 hrs. Create table burn1(col1 char(4), col2 numeric identity). Inserted several rows. Select * from burn1 returns:<br>
<br>
col1 col2<br>
---- --------------------<br>
aaaa 1<br>
aaab 2<br>
aaac 3<br>
aaad 4<br>
<br>
When the first insert is done, a block of 500000000000000 numbers is taken as the first block of numbers.<br>
<br>
0815 hrs. shutdown with nowait.<br>
<br>
With the nowait, the server is unable to write the current identity number back to disk, so the rest of the<br>
500000000000000 block of numbers is lost.<br>
<br>
0816 hrs. startserver<br>
<br>
0817 hrs. insert 1 row into burn1. select * returns:<br>
<br>
col1 col2<br>
---- --------------------<br>
aaaa 1<br>
aaab 2<br>
aaac 3<br>
aaad 4<br>
aaae 500000000000002<br>
<br>
As expected, we lost the first block of 5000000000000 numbers. The insert of 1 row above causes the server to get the next block of 500000000000000 numbers.<br>
<br>
0818 hrs. Change identity burning set factorfrom 5000 to 10.<br>
<br>
1> sp_configure "identity burning set factor", 10<br>
2> go<br>
<br>
Configuration option changed. (return status = 0)<br>
<br>
1> sp_configure<br>
2> go<br>
<br>
name minimum maximum config_<br>
value run_value<br>
---------------------------- ----------- ----------- ------------ ----<br>
-------<br>
...<br>
...<br>
identity burning set factor 1 9999999 10<br>
5000 <br>
<br>
0820 hrs. shutdown with nowait again. <br>
<br>
With the nowait, the server is unable to write the current identity number back to disk, so the rest of the second 500000000000000 block of numbers is lost.<br>
<br>
0822 hrs. startserver<br>
<br>
0823 hrs. Check that identity burning set factor has changed. <br>
<br>
1> sp_configure<br>
2> go<br>
<br>
name minimum maximum config_<br>
value run_value<br>
---------------------------- ----------- -------<br>
---- ------------ -----------<br>
...<br>
...<br>
identity burning set factor 1 9999999 10<br>
10 <br>
<br>
0825 hrs. insert 1 row into burn1. select * returns: <br>
<br>
col1 col2<br>
---- --------------------<br>
aaaa 1<br>
aaab 2<br>
aaac 3<br>
aaad 4<br>
aaae 500000000000002<br>
aaaf 1000000000000003 <br>
<br>
As expected, the server lost the second block of 5000000000000 numbers. The insert of 1 row above causes the server to get the next block of 1000000000000 numbers. <br>
<br>
Note: <br>
The above output from the select, which shows that the<br>
server deleted the second large block of numbers, often<br>
confuses users into believing that no change to the identity<br>
parameter occurred. <br>
<br>
<br>
0827 hrs. shutdown with nowait again. <br>
<br>
0830 hrs. startserver <br>
<br>
0825 hrs. insert 1 row into burn1. select * displays: <br>
<br>
col1 col2<br>
---- --------------------<br>
aaaa 1<br>
aaab 2<br>
aaac 3<br>
aaad 4<br>
aaae 500000000000002<br>
aaaf 1000000000000003<br>
aaag 1001000000000004<br>
<br>
As expected, the server lost the first block of 10000000000 numbers. The insert of 1 row above causes the server to get the next block of 1000000000000 numbers.<br>
<br>
This last step verifies that the identity burning set factor change worked. <br>
<br>
Happy Sybaseing, Brian
<br>
Background: What is the identity burning set factor? <br>
<br>
The identity burning set factor configuration parameter is a percentage in decimal form x 10 million.<br>
<br>
The default value, 5000, represents .05%, or .0005.<br>
<br>
When an identity column is defined in a table, the server automatically assigns a unique sequential number for that identity column during inserts. To avoid excessive I/O, Adaptive Server Enterprise keeps blocks of numbers available in memoryfor use in identity values and keeps track of the current pointer in that block in memory.<br>
<br>
The number of values in the block is controlled by the identity burning set factor. The identity column is a numeric datatype with a pre-defined precision. The server uses the possible range of values to determine which numbers are reserved.<br>
<br>
For example, an identity column, "colA," is defined as numeric(7,0). The values of this column range from 1 to 9,999,999. Using the default burning set factor of 5000, .05% of the values are made available at a time. Therefore, the size of a block of numbers reserved in memory is .0005 (or .05%) x (9,999,999 +1) = 5000 values.<br>
<br>
If the server shuts down unexpectedly, all unused numbers in the current reserved block (in memory) are lost. When the server restarts, the next insert starts with the next block. Therefore, abnormal shutdowns can cause large gaps in the identity column. An orderly shutdown (normal) does not delete identity values.<br>
<br>
Note: <br>
A shutdown with nowait is an unexpected shutdown and<br>
causes the block of numbers to be lost. For more<br>
information, see the Adaptive Server Enterprise System<br>
Administration Guide, the Transact-SQL User's Guide,<br>
and the Adaptive Server Enterprise Reference Guide.<br>
<br>
<br>
Example: How Adaptive Server "loses" block values<br>
<br>
In this example, we use the above identity column, colA, and perform a shutdown with nowait: <br>
<br>
1.After 5 inserts into the table we have: <br>
<br>
colA<br>
-------<br>
1<br>
2<br>
3<br>
4<br>
5<br>
<br>
<br>
2.We now shut down the server with nowait, then re-start the server. <br>
<br>
select colA from table: <br>
<br>
colA<br>
-------<br>
1<br>
2<br>
3<br>
4<br>
5<br>
<br>
3.We perform an insert into the table, then select colA again:<br>
<br>
colA<br>
-------<br>
1<br>
2<br>
3<br>
4<br>
5<br>
5002<br>
<br>
4.If we perform a shutdown with nowait again, then repeat the insert and select colA again, colA displays as<br>
follows:<br>
<br>
colA<br>
-------<br>
1<br>
2<br>
3<br>
4<br>
5<br>
5002<br>
10003<br>
<br>
<br>
Note: <br>
The starting value in the next block almost always will not<br>
be the first value in the new block. This is because of a<br>
current value that is stored in the dbtable info. When the<br>
block is lost, the server goes to the next block and the next<br>
value in the dbtable info. In the above case, the last value in<br>
the dbtable was 1.<br>
<br>
<br>
Correcting identity column gaps <br>
<br>
You can fix the rows containing the large numbers to correct gaps in the identity column. Perform the following steps:<br>
<br>
1.Turn on identity_insert.<br>
<br>
1> set identity_insert table_name on<br>
<br>
2> go<br>
<br>
2.Record the row(s) information. Because you cannot update an identity column, you must delete the row(s) and insert them again with the correct identity values.<br>
<br>
3.Correct all rows in error.<br>
<br>
4.bcp out the data from the table.<br>
<br>
5.Turn off identity_insert.<br>
<br>
1> set identity_insert table_name off<br>
<br>
2> go<br>
<br>
6.Drop the table and re-create it. This step resets the identity column's auto-start number to 1. <br>
<br>
7.bcp the data back into the table using the -E option to maintain the identity values that appear in the host file. <br>
<br>
Note: <br>
The -E option tells the server not to use the auto-insert<br>
identity numbers and to use the identity numbers included<br>
in the bcp data.<br>
<br>
<br>
The next identity number should be one greater than the largest identity number in the table. <br>
<br>
<br>
Understanding the identity grab size<br>
<br>
The identity grab size parameter allows a server process to reserve a block of identity column values for inserts into tables with identity columns.<br>
<br>
What this means is that a particular server process gets its own block of numbers to use. This is useful if a particular server process needs to insert contiguous identity values. Identity grab size is a server-wide parameter, so do not set it to a high value. Set identity grab size only to a value large enough to accommodate the largest group of records you want to insert into contiguous rows. The default is 1. <br>
<br>
Troubleshooting the identity burning set factor<br>
<br>
In this example, performing shutdown with nowait confuses the user into believing that the identity burning set factor did not re-set.<br>
<br>
0800 hrs. Create table burn1(col1 char(4), col2 numeric identity). Inserted several rows. Select * from burn1 returns:<br>
<br>
col1 col2<br>
---- --------------------<br>
aaaa 1<br>
aaab 2<br>
aaac 3<br>
aaad 4<br>
<br>
When the first insert is done, a block of 500000000000000 numbers is taken as the first block of numbers.<br>
<br>
0815 hrs. shutdown with nowait.<br>
<br>
With the nowait, the server is unable to write the current identity number back to disk, so the rest of the<br>
500000000000000 block of numbers is lost.<br>
<br>
0816 hrs. startserver<br>
<br>
0817 hrs. insert 1 row into burn1. select * returns:<br>
<br>
col1 col2<br>
---- --------------------<br>
aaaa 1<br>
aaab 2<br>
aaac 3<br>
aaad 4<br>
aaae 500000000000002<br>
<br>
As expected, we lost the first block of 5000000000000 numbers. The insert of 1 row above causes the server to get the next block of 500000000000000 numbers.<br>
<br>
0818 hrs. Change identity burning set factorfrom 5000 to 10.<br>
<br>
1> sp_configure "identity burning set factor", 10<br>
2> go<br>
<br>
Configuration option changed. (return status = 0)<br>
<br>
1> sp_configure<br>
2> go<br>
<br>
name minimum maximum config_<br>
value run_value<br>
---------------------------- ----------- ----------- ------------ ----<br>
-------<br>
...<br>
...<br>
identity burning set factor 1 9999999 10<br>
5000 <br>
<br>
0820 hrs. shutdown with nowait again. <br>
<br>
With the nowait, the server is unable to write the current identity number back to disk, so the rest of the second 500000000000000 block of numbers is lost.<br>
<br>
0822 hrs. startserver<br>
<br>
0823 hrs. Check that identity burning set factor has changed. <br>
<br>
1> sp_configure<br>
2> go<br>
<br>
name minimum maximum config_<br>
value run_value<br>
---------------------------- ----------- -------<br>
---- ------------ -----------<br>
...<br>
...<br>
identity burning set factor 1 9999999 10<br>
10 <br>
<br>
0825 hrs. insert 1 row into burn1. select * returns: <br>
<br>
col1 col2<br>
---- --------------------<br>
aaaa 1<br>
aaab 2<br>
aaac 3<br>
aaad 4<br>
aaae 500000000000002<br>
aaaf 1000000000000003 <br>
<br>
As expected, the server lost the second block of 5000000000000 numbers. The insert of 1 row above causes the server to get the next block of 1000000000000 numbers. <br>
<br>
Note: <br>
The above output from the select, which shows that the<br>
server deleted the second large block of numbers, often<br>
confuses users into believing that no change to the identity<br>
parameter occurred. <br>
<br>
<br>
0827 hrs. shutdown with nowait again. <br>
<br>
0830 hrs. startserver <br>
<br>
0825 hrs. insert 1 row into burn1. select * displays: <br>
<br>
col1 col2<br>
---- --------------------<br>
aaaa 1<br>
aaab 2<br>
aaac 3<br>
aaad 4<br>
aaae 500000000000002<br>
aaaf 1000000000000003<br>
aaag 1001000000000004<br>
<br>
As expected, the server lost the first block of 10000000000 numbers. The insert of 1 row above causes the server to get the next block of 1000000000000 numbers.<br>
<br>
This last step verifies that the identity burning set factor change worked. <br>
<br>
Happy Sybaseing, Brian