The number of open objects in the sybase database is increasing badly
and having this error :
Increase the config parameter 'number of open objects' to avoid descriptor reuse.
At first the values of `open objects' was 100000
sp_monitorconfig "open objects"
go
Name Num_free Num_active Pct_act Max_Used Reuse_cnt Instance_Name
number of open objects 1223 90380 95.25 92380 9269
I changed the value from 100000 to 160000 and still the value is increasing.
Is there a way I can know what are the objects increasing ?
what are the causes of increasing the values and how to stop increasing in such way ?
When I've seen this issue (ever increasing descriptor usage for open objects), I've tracked the issue back to an application that is generating a large volume of prepared statements (eg, instead of re-using a prepared statement for repetitive DML statements, the app creates a new prepared statement for each DML statement).
In Sybase (now SAP) ASE, prepared statements are converted into 'lightweight procedures' (aka LWPs; think 'temporary procedures') which in turn require their own descriptor.
To find out if this is a LWP issue:
grant sybase_ts_role to your login
run dbcc traceon(3604)
run dbcc des
NOTE: dbcc des will generate a LOT of output so make sure you capture it to a file!!
In the 'dbcc des' output the LWP's show up with the following attributes:
exist in login's tempdb
have negative object id's
have names like *dddddddddddddd_hhhhhh (where 'd' == decimal digit, 'h' == hex digit) OR ...
may have names like *aadddddddddd_dddddddddaa* ('d' == decimal, 'a' == alphabetical character)
objssystat = O_PROC
objsysstat2 = O2_LWP
To find the offending connection(s) ... you may be able to pull the spid from the LWP name (dbcc des output) or from master..monCachedProcedures column (look for procs with names like *sq##########ss* and *ss#########ss* ... something that looks like system-/auto-generated names).
NOTE: Depending on ASE version (11? 12? 15? 16?) the LWP name format may vary so you may have to do some digging to find the associated spid.
For LWPs where the spid is part of the name, the spid is likely the first 5 digits of the (dbcc des) object name; so for the following we see the spid = 61
*00061000000606_9d5317
*00061000000626_a149eb
*00061000000606_9d5317
*00061000000589_63ea4e
This topic has come up many times over the years, and you can review some of my ramblings in the following links: here, here, here and here
Related
I have a Number field in DB and Oracle APEX.
My Issue is:
If Users want to entry the number data with this format "1.000.000,01", then takes Charakter Error that the entry must be Number.
How can I solve this problem in Application Layer ? In Database Layer there are some solutions , but in Application Layer so far I can not find any solution.
As Summary: I want to entry number as 1.000.000,12 in Application and I want to see it in the same format.
NOT: A procedure runs in the Application to insert the data in DB.
You can/should set appropriate format mask, e.g. 999G999G990D00 where
G represents thousands character (dot in your case)
D represents decimal character (comma in your case)
But, where do you set NLS numeric characters (represented by G and D)? In Apex 20.2, it is to be set in:
application builder
shared components
globalization attributes
security
initialization PL/SQL code - in here, you'll probably see what they are set to. Change those values, if necessary. For example:
begin
execute immediate q'[alter session set nls_numeric_characters = ',.']';
execute immediate q'[alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss']';
end;
In a .CFC file, within a CFfunction and with CFargument tags.
<cfscript>
var sp=new storedproc();
sp.setDatasource(variables.datasource);
sp.setProcedure("storedProcedure_INSERT");
sp.addParam(cfsqltype="cf_sql_integer",type="in",value=arguments.one);
sp.addParam(cfsqltype="cf_sql_integer",type="in",value=arguments.two);
sp.addParam(cfsqltype="cf_sql_integer",type="in",value=arguments.three);
sp.addParam(cfsqltype="cf_sql_integer",type="in",value=arguments.four);
sp.addProcResult(name="results",resultset=1);
//writeDump(sp);break; //This dump is reached
var spObj=sp.execute(); //blows up here; this is never reached
writeDump(spObj);break; //This is never reached, either.
var spResults=spObj.getProcResultSets().results;
A shiny nickle to anyone who can tell me why the sp.execute() is blowing up with message
"Cannot find results key in structure.
The specified key, results, does not exist in the structure."
I've used this psuedo-code many, may times in the past, and never had it do this. I'm connected to a MSSQL Server 2012 DB, everything's cricket in CF Admin, and other SPs are working properly. The stack trace doesn't even include any of MY code at all o_O
The error occurred in C:/ColdFusion10/cfusion/CustomTags/com/adobe/coldfusion/base.cfc: line 491
Called from C:/ColdFusion10/cfusion/CustomTags/com/adobe/coldfusion/storedproc.cfc: line 142
Called from //hq-devfs/development$/websites/myProject/cfc/mySOAPWSDLs.cfc: line 123
And SO is blowing up if I try and paste anymore of that. Google has...not been helpful ._.
Short answer: The error means you are trying to retrieve a resultset from the stored procedure, when it does not actually return one. A simple solution is to add a SELECT to the end of your procedure, so it returns a resultset containing the data you need. Then your original code will work:
SELECT ##ROWCOUNT AS NumOfRowsAffected;
Longer answer:
The method you are using, addProcResult(), is the equivalent of <cfprocresult>. It is intended to capture a resultset returned from a stored procedure. (Due to CF's poor choice of attribute names, a lot of people think "resultset" means the storedproc "result" structure, but they are two totally different things). A "resultset" is a query object", in CF parlance.
While all four (4) of the primary sql statements return some result, not all of them return a "query object"
Only SELECT statements generate a "query object"
INSERT/UPDATE/DELETE statements simply return the number of rows affected. They do not generate a "query object".
Since your stored procedure performs an INSERT, it does not generate a "query object". Hence the error when you try and grab the non-existent query here:
sp.addProcResult(name="results",resultset=1);
The simple solution is to add a SELECT statement to the end of your stored procedure, so that it does return a query object. Then your code will work as expected.
As an aside, I suspect you were actually trying to grab the "result" structure, but used the wrong method. The equivalent of <cfstoredproc result=".."> is getPrefix(). Though that would not work here anyway. According to the docs, it does not contain the number of rows affected. Probably because stored procedures can execute multiple statements, each one potentially returning a row count, so there is not just a single value to return.
How can I make Sybase's database engine return an unsorted list of records in non-numeric order?
~~~
I have an issue where I need to reproduce an error in the application where I select from a table where the ID is generated in sequence, but the ID is not the last one in the selection.
Let me explain.
ID STATUS
_____________
1234 C
1235 C
1236 O
Above is 3 IDs. I had code where these would be the results of a
select #p_id = ID from table where (conditions).
However, there wasn't a clause to check for status = 'O' (open). Remember Sybase saves the last returned record into a variable.
~~~~~
I'm being asked to give the testing team something that will make the results not work. If Sybase selects the above in an unordered list, it could appear in ascending order, or, if the database engine needs to change blocks of stored data or something technical magic stuff, the order could be messed up. The original error was when the procedure would return say 1234 instead of 1236.
Is there a way that I can have a 100% guarantee that Sybase will search over a block of data and have to double back, effectively 'breaking' the ascending search, and returning not the last record, but any other one? (all records except the maximum will end up erroring, because they are all 'Closed')
I want some sort of magical SQL code that will make sure things don't search the table in exactly numeric order. Ideally I'd like to not have to change the procedure, as the test team want to see the exact same procedure breaking (as easy as plonking a order by id desc would fudge the results).
If you don't specify an order, there is no way to guarantee the return order of the results. It will be however the index is built - and can depend on the order of insertion, the type of index, and the content of index keys.
It's generally a bad idea to do those sorts of singleton SELECTs. You should always specify a specific record with the WHERE clause, or use a cursor, or TOPn or similar. The problem comes when someone tries to understand your code, because some databases when they see multiple hits take the first value, some take the last value, some take a random value (they call that "implementation-defined"), and some throw an error.
Is this by any chance related to 1156837? :)
I'm using a Sequence to generate an id for me, but I use that sequence from my Java application. So say for example my last Id is 200.
If I add an entry with .sql by by using 201 as an id instead of doing seq.nextval. What would happen when my java application calls seq.nextval? Is sequence smart enough to check the max available number or it will just return 201?
It will just return 201, as the sequence has no idea what the numbers are used for.
Note: It may return, say, 220 if you have specified that the sequence has to cache values for some session (see the Oracle manual about CREATE SEQUENCE for more details)
Sequences just provide a way to "select" numbers that auto increment.
You will get 201 because they don't check anything, they just store the last value retrieved and when you query it again, it will return the next value in the sequence.
It will return 201.
You could also use nextval from JDBC, and then use that value to do the insert:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("select seq.nextval from dual");
rs.next();
int yourId = rs.getInt(1);
// then use yourId to do the insert
This way you can insert using a number, and also keep the sequence the way it should be.
What nextval returns on the next call from your Java app depends on a number of factors:
If you run in a clustered environment, which node you next speak to. Each node will preallocate a pool of sequence values;
Whether or not the node you're talking to has been restarted. If this happens the pool of sequence values will tend to be "lost" (meaning skipped);
The step value of the sequence; and
Whether are transactions have called nextval on the sequence.
Sequences are loosely ordered, not absolutely ordered.
But Oracle has no idea what you do with sequence values so if you insert a 201 into the database, the sequence will happily return 201 completely oblivious to the inserted value as the two are basically unrelated.
It is never a good idea to mix sequence-generated values with manual inserts because then everything gets mixed up.
Not sure if it helps in your situation, but remember that you can ask for the current value of the sequence (with seq.currval or similar) so that you can check if already exists in the table due to a manual insert and, if necessary, ask for another nextval
On my app i am creating a real time trace (not sure how yet but i am!) and on the sp_trace_create function in SQlServer, i know that the #maxfilesize defaults to 5, but on my app its going to be stopped when the user wants to stop it...any ideas how this can be done?
Because i dont want to have to save the files...im not sure how the rollover works?
Right now im putting it on a timer loop that queries the database with all the specified events on it with a maximum file size of 1(usually doesnt take more then about 2 seconds), merges with the old lot of data in my dgview and deletes the original file. this goes round until the user tells it to stop which will stop the timer from querying the database. Not a solid method but i guess its a start! All i need now is the find out the datatypes of the columns as when im setting my values in the filters they need to go in as the matching datatype to the column... anyone have any clue where i can get a list of the datatypes? msdn have the list but no types...
To start a trace with file rollover, instead of stopping at a maximum size, start the trace like so:
exec #rc = sp_trace_create #TraceID output, 2, N'InsertFileNameHere', #maxfilesize, NULL
where #maxfilesize will define the size reached before a new rollover file will be created.
WARNING: be very careful about performing unlimited tracing. If you fill up a production disc, it's your head not mine!
You can stop a running trace like so:
EXEC sp_trace_setstatus #ID, 0
EXEC sp_trace_setstatus #ID, 2
where #ID is the ID of the trace you want to stop.
See this post.
According to the documentation, what you want to do is not possible:
[ #maxfilesize = ] max_file_size
Specifies the maximum size in megabytes (MB) a trace file can grow. max_file_size is bigint, with a default value of 5.
If this parameter is specified without the TRACE_FILE_ROLLOVER option, the trace stops recording to the file when the disk space used exceeds the amount specified by max_file_size.
I don't see why you can't just cycle through the files and load them into a table or your app. Shouldn't be that hard.