Subject | Should this program hit deadlock? (or... |
---|---|
Author | learntrade |
Post date | 2006-10-19T22:48:46Z |
"firebird deadlock vs isc_tpb_wait/etc. issue, or ?" revisited.)
As the subject asks, Should this program (below) hit deadlock?
If not, should I take/report this issue elsewhere?
(this version fb1.5.? classic, and original also fb2rc5 superserver
reproducibility)
(early "ps" - thanks for the info on the 64bit generators)
(Is it possible the fb1.5 deadlock detection/reporting improvements
got a little too aggressive?)
This minimal program (using direct API) tends to hit a deadlock on fb
version/build of that original post.
FWIW, The original posted program also hit deadlock on fb2rc5, (for
fb2rc5, superserver [installed superserver to try, didn't try fb2rc5
classic].)
winxp, sp2, 3.6GHz, HT-CPU
Run script to create database.
Drop source code into firebird examples directory and build.
open two command prompts, position to trydeadlock2 executable location.
Start in rapid succession (on multi-processor, or hyper-threaded CPU
system) trydeadlock2 in both windows. I expect in one of them you
will eventually see:
[
PROBLEM ON "update tbl_sysuids set col2 = col2 + 1 where col1 = 7".
deadlock
-update conflicts with concurrent update
SQLCODE:-913
]
build command was:
bcc32 -I..\include trydeadlock2.c ..\lib\fbclient_bor.lib
(The main program comment is bogus, in particular the URL referencing
the license is no longer valid. Hopefully I am compliant.)
source code for trydeadlock2.c:
/***************************************************/
/*cloned/modified from firebird example api1.c,
pulled pieces from elsewhere, at least api16.c and api15.c */
/*
* Program type: API Interface
*
* Description:
* This program creates a new database, given an SQL statement
* string. The newly created database is accessed after its
* creation, and a sample table is added.
*
* The SQLCODE is extracted from the status vector and is used
* to check whether the database already exists.
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "example.h"
#include <ibase.h>
int pr_error (long *, char *);
static char *update_data = "update tbl_sysuids set col2 = col2 + 1
where col1 = 7" ;
int main (ARG(int, argc), ARG(char **, argv))
ARGLIST(int argc)
ARGLIST(char **argv)
{
isc_db_handle newdb = NULL; /* database handle */
isc_tr_handle trans = NULL; /* transaction handle */
ISC_STATUS_ARRAY status; /* status vector */
long sqlcode; /* SQLCODE */
char create_db[160]; /* 'create database'
statement */
char new_dbname[128];
static char isc_tpb[5] = {isc_tpb_version1,
isc_tpb_write,
isc_tpb_read_committed,
isc_tpb_wait,
isc_tpb_no_rec_version};
char user_name[31];
char password[31];
// char *copy ;
char *p ;
char *dpb ;
short dpb_length = 0;
// long l,sweep_interval = 16384;
unsigned ui ;
if (argc > 1)
strcpy(new_dbname, argv[1]);
else
strcpy(new_dbname, "c:\\temp\\junkdb2.gdb");
strcpy(user_name, "SYSDBA") ;
strcpy(password, "masterkey") ;
/********************/
/* From api15.c - used for database attachment */
dpb = (char *) malloc(1);
p = dpb;
// *p++ = '\1';
*p = '\1';
dpb_length = 1 ;
/* Add user and password to dpb, much easier. The dpb will be
** new memory.
*/
isc_expand_dpb(&dpb, (short *) &dpb_length,
isc_dpb_user_name, user_name,
isc_dpb_password, password, NULL);
/********************/
if (isc_attach_database(status, 0, new_dbname, &newdb, dpb_length,
dpb))
if (pr_error(status, "attach database"))
return 1;
for(ui = 0 ; ui < 1000000 ; ui++)
{
if (isc_start_transaction (status, &trans, 1, &newdb,
sizeof(isc_tpb), isc_tpb))
{ERREXIT(status, 1)};
if (isc_dsql_execute_immediate(status, &newdb, &trans, 0,
update_data, 3, NULL))
if (pr_error(status, update_data))
return 1;
isc_commit_transaction(status, &trans);
if (status[0] == 1 && status[1])
{
fprintf(stderr, "Error on write\n");
isc_print_status(status);
}
if(!(ui % 5000))
printf("\rui %u", ui) ;
}
printf("Successfully updated database.\n\n");
isc_detach_database(status, &newdb);
return 0;
}
/*
* Print the status, the SQLCODE, and exit.
* Also, indicate which operation the error occured on.
*/
int pr_error (ARG(long *, status), ARG(char *, operation))
ARGLIST(long * status)
ARGLIST(char * operation)
{
printf("[\n");
printf("PROBLEM ON \"%s\".\n", operation);
isc_print_status(status);
printf("SQLCODE:%d\n", isc_sqlcode(status));
printf("]\n");
return 1;
}
/***************************************************/
/***************************************************/
For script to create database file program runs against see:
http://tech.groups.yahoo.com/group/firebird-support/message/80353
As the subject asks, Should this program (below) hit deadlock?
If not, should I take/report this issue elsewhere?
(this version fb1.5.? classic, and original also fb2rc5 superserver
reproducibility)
(early "ps" - thanks for the info on the 64bit generators)
(Is it possible the fb1.5 deadlock detection/reporting improvements
got a little too aggressive?)
This minimal program (using direct API) tends to hit a deadlock on fb
version/build of that original post.
FWIW, The original posted program also hit deadlock on fb2rc5, (for
fb2rc5, superserver [installed superserver to try, didn't try fb2rc5
classic].)
winxp, sp2, 3.6GHz, HT-CPU
Run script to create database.
Drop source code into firebird examples directory and build.
open two command prompts, position to trydeadlock2 executable location.
Start in rapid succession (on multi-processor, or hyper-threaded CPU
system) trydeadlock2 in both windows. I expect in one of them you
will eventually see:
[
PROBLEM ON "update tbl_sysuids set col2 = col2 + 1 where col1 = 7".
deadlock
-update conflicts with concurrent update
SQLCODE:-913
]
build command was:
bcc32 -I..\include trydeadlock2.c ..\lib\fbclient_bor.lib
(The main program comment is bogus, in particular the URL referencing
the license is no longer valid. Hopefully I am compliant.)
source code for trydeadlock2.c:
/***************************************************/
/*cloned/modified from firebird example api1.c,
pulled pieces from elsewhere, at least api16.c and api15.c */
/*
* Program type: API Interface
*
* Description:
* This program creates a new database, given an SQL statement
* string. The newly created database is accessed after its
* creation, and a sample table is added.
*
* The SQLCODE is extracted from the status vector and is used
* to check whether the database already exists.
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "example.h"
#include <ibase.h>
int pr_error (long *, char *);
static char *update_data = "update tbl_sysuids set col2 = col2 + 1
where col1 = 7" ;
int main (ARG(int, argc), ARG(char **, argv))
ARGLIST(int argc)
ARGLIST(char **argv)
{
isc_db_handle newdb = NULL; /* database handle */
isc_tr_handle trans = NULL; /* transaction handle */
ISC_STATUS_ARRAY status; /* status vector */
long sqlcode; /* SQLCODE */
char create_db[160]; /* 'create database'
statement */
char new_dbname[128];
static char isc_tpb[5] = {isc_tpb_version1,
isc_tpb_write,
isc_tpb_read_committed,
isc_tpb_wait,
isc_tpb_no_rec_version};
char user_name[31];
char password[31];
// char *copy ;
char *p ;
char *dpb ;
short dpb_length = 0;
// long l,sweep_interval = 16384;
unsigned ui ;
if (argc > 1)
strcpy(new_dbname, argv[1]);
else
strcpy(new_dbname, "c:\\temp\\junkdb2.gdb");
strcpy(user_name, "SYSDBA") ;
strcpy(password, "masterkey") ;
/********************/
/* From api15.c - used for database attachment */
dpb = (char *) malloc(1);
p = dpb;
// *p++ = '\1';
*p = '\1';
dpb_length = 1 ;
/* Add user and password to dpb, much easier. The dpb will be
** new memory.
*/
isc_expand_dpb(&dpb, (short *) &dpb_length,
isc_dpb_user_name, user_name,
isc_dpb_password, password, NULL);
/********************/
if (isc_attach_database(status, 0, new_dbname, &newdb, dpb_length,
dpb))
if (pr_error(status, "attach database"))
return 1;
for(ui = 0 ; ui < 1000000 ; ui++)
{
if (isc_start_transaction (status, &trans, 1, &newdb,
sizeof(isc_tpb), isc_tpb))
{ERREXIT(status, 1)};
if (isc_dsql_execute_immediate(status, &newdb, &trans, 0,
update_data, 3, NULL))
if (pr_error(status, update_data))
return 1;
isc_commit_transaction(status, &trans);
if (status[0] == 1 && status[1])
{
fprintf(stderr, "Error on write\n");
isc_print_status(status);
}
if(!(ui % 5000))
printf("\rui %u", ui) ;
}
printf("Successfully updated database.\n\n");
isc_detach_database(status, &newdb);
return 0;
}
/*
* Print the status, the SQLCODE, and exit.
* Also, indicate which operation the error occured on.
*/
int pr_error (ARG(long *, status), ARG(char *, operation))
ARGLIST(long * status)
ARGLIST(char * operation)
{
printf("[\n");
printf("PROBLEM ON \"%s\".\n", operation);
isc_print_status(status);
printf("SQLCODE:%d\n", isc_sqlcode(status));
printf("]\n");
return 1;
}
/***************************************************/
/***************************************************/
For script to create database file program runs against see:
http://tech.groups.yahoo.com/group/firebird-support/message/80353