ShareLock and ExclusiveLock with postgres database - sql

I was checking the lock in logs of one application which is running in heroku and its shows so many lock from delayed_jobs and increment_counter, also these time i got so many timeouts
sql_error_code = 00000 LOG: process 129728 still waiting for ShareLock on
transaction 1296511670 after 1000.149 ms
2017-06-02T16:24:58+00:00 app
postgres.129728 - - [TEST] [7-2] sql_error_code = 00000 DETAIL: Process
holding the lock: 129457. Wait queue: 129728.
02 Jun 2017 20:24:58.338198 <134>1 2017-06-02T16:24:58+00:00 app
postgres.129728 - - [TEST] [7-3] sql_error_code = 00000 CONTEXT: while
locking tuple (75,2) in relation "delayed_jobs"
LOG: process 129429 acquired ExclusiveLock on tuple (878044,83) of relation
16953 of database 16385 after 3220.356 ms
02 Jun 2017 20:24:58.338591 <134>1 2017-06-02T16:24:58+00:00 app
postgres.129728 - - [TEST] [7-4] sql_error_code = 00000 STATEMENT: UPDATE
"delayed_jobs" SET locked_at = '2017-06-02 16:24:57.033870', locked_by =
'host:a96aff72dae123123e pid:4' WHERE id IN (SELECT id FROM
"delayed_jobs" WHERE ((run_at <= '2017-06-02 16:24:57.032776' AND (locked_at
IS NULL OR locked_at < '2017-06-02 12:24:57.032817') OR locked_by =
'host:a96aff72dae123123e pid:4') AND failed_at IS NULL)
ORDER BY priority ASC, run_at ASC LIMIT 1 FOR UPDATE) RETURNING *
sql_error_code = 00000 DETAIL: Process holding the lock: 129495. Wait queue:
3276.
02 Jun 2017 20:25:09.279197 <134>1 2017-06-02T16:25:08+00:00 app
postgres.3276
- - [TEST] [7-3] sql_error_code = 00000 CONTEXT: while updating tuple
(878034,120) in relation "messages"
02 Jun 2017 20:25:09.279248 <134>1 2017-06-02T16:25:08+00:00 app
postgres.3276
- - [TEST] [7-4] sql_error_code = 00000
STATEMENT: UPDATE "messages" SET
"item_no" = COALESCE("item_no", 0) + 1 WHERE "messages"."id" =
48290879
I think this is not a normal lock, is there any way to fix these kind of lock?

I don't know what you consider a "normal" kind of lock to be. This is the normal kind of lock you get when multiple transactions try to update (or to select for update) on the same tuple at the same time.
But why are the transactions that are taking these locks holding on to them for at least a second? Are the transactions inherently slow, or are they getting distracted?

Related

SQL Server does not perform job logic correct

I have some maintenance job, here is structure:
Step 1 and 3 just checking where are
Step 1 and 3 just checking where is specific database is currently resides - is it primary or secondary replica
If sys.fn_hadr_is_primary_replica ( 'DATABASENAME') <> 1
BEGIN
RAISERROR ('Not PRIMARY REPLICA FOR DATABASE NAME', -- Message text.
16, -- Severity.
1 -- State.
);
END
STEP 2 and 4 just performs backup of specific database using Ola script
EXECUTE [dbo].[DatabaseBackup]
#Databases = 'SOMEDB',
#Directory = 'SOMESHARE',
#BackupType = 'FULL',
#Verify = 'Y',
#CleanupTime = 336,
#CheckSum = 'Y',
#LogToTable = 'Y',
#Compress = 'Y'
Step 1 moves job execution to Step 3 in case of database is not on primary replica now
Step 3 quit with success in case of failure
This works well on secondary replica and job quit with success with failed first and third step
But on primary replica there absolutely strange things happening and SQL agent can mix step or doing logic that should not happen anyway. Looks like following
Just rebooted the server and now everything working fine , its probably happened because of installing multiple windows and sql server patches since last 5 days without reboot whole server.

How to check active transactions in SQL Server 2014?

I am using SQL Server 2014 and want to know how to check my active transactions?
Query with sys.sysprocesses
SELECT * FROM sys.sysprocesses WHERE open_tran = 1
DBCC OPENTRAN : helps to identify active transactions that may be preventing log truncation. DBCC OPENTRAN displays information about the oldest active transaction and the oldest distributed and nondistributed replicated transactions, if any, within the transaction log of the specified database. Results are displayed only if there is an active transaction that exists in the log or if the database contains replication information. An informational message is displayed if there are no active transactions in the log.
sys.dm_tran_active_transactions
Returns information about transactions for the instance of SQL Server.
Syntax
Wondering about Transaction ?
A transaction is a single unit of work. If a transaction is
successful, all of the data modifications made during the transaction
are committed and become a permanent part of the database.
Find more at docs
If you want to know more details about active sessions like
session ID, Host Name,Login Name,Transaction ID,Transaction Name,Trnasaction Begin Time,Databse ID,Database Name you can use below sql query
SELECT
trans.session_id AS [SESSION ID],
ESes.host_name AS [HOST NAME],login_name AS [Login NAME],
trans.transaction_id AS [TRANSACTION ID],
tas.name AS [TRANSACTION NAME],tas.transaction_begin_time AS [TRANSACTION
BEGIN TIME],
tds.database_id AS [DATABASE ID],DBs.name AS [DATABASE NAME]
FROM sys.dm_tran_active_transactions tas
JOIN sys.dm_tran_session_transactions trans
ON (trans.transaction_id=tas.transaction_id)
LEFT OUTER JOIN sys.dm_tran_database_transactions tds
ON (tas.transaction_id = tds.transaction_id )
LEFT OUTER JOIN sys.databases AS DBs
ON tds.database_id = DBs.database_id
LEFT OUTER JOIN sys.dm_exec_sessions AS ESes
ON trans.session_id = ESes.session_id
WHERE ESes.session_id IS NOT NULL
and you will get the result something like
Translation the 3. query that Tharif comments.
select transaction_id, name, transaction_begin_time
,case transaction_type
when 1 then '1 = Read/write transaction'
when 2 then '2 = Read-only transaction'
when 3 then '3 = System transaction'
when 4 then '4 = Distributed transaction'
end as transaction_type
,case transaction_state
when 0 then '0 = The transaction has not been completely initialized yet'
when 1 then '1 = The transaction has been initialized but has not started'
when 2 then '2 = The transaction is active'
when 3 then '3 = The transaction has ended. This is used for read-only transactions'
when 4 then '4 = The commit process has been initiated on the distributed transaction'
when 5 then '5 = The transaction is in a prepared state and waiting resolution'
when 6 then '6 = The transaction has been committed'
when 7 then '7 = The transaction is being rolled back'
when 8 then '8 = The transaction has been rolled back'
end as transaction_state
,case dtc_state
when 1 then '1 = ACTIVE'
when 2 then '2 = PREPARED'
when 3 then '3 = COMMITTED'
when 4 then '4 = ABORTED'
when 5 then '5 = RECOVERED'
end as dtc_state
,transaction_status, transaction_status2,dtc_status, dtc_isolation_level, filestream_transaction_id
from sys.dm_tran_active_transactions
or use DBCC command
DBCC OPENTRAN
The Most Usefull method is;
DBCC opentran()
When You check, you will get below message;
Oldest active transaction:
SPID (server process ID): 190
UID (user ID) : -1
Name : implicit_transaction
LSN : (500549:37333:1)
Start time : Dec 4 2021 10:36:21:673AM
And if you run DBCC opentran several times and you always get same server process ID then system then A transaction is stuck in the database.
Therefore, it is necessary to first look at the SPID detail with the code below and then kill that SPID process.
exec sp_who2 190
exec sp_lock 190
KILL 190

sql timeout on view

We have an Access application in our office that takes data from SQL Server Management Studio 2012 different views (order tables joined with other tables from different companies) and put them in a single Access table for statistics. Now the problem is that when the view becomes complicate, if I execute it from view design it gives error after 30 sec and Access gives same error when I open the view from Access so I cannot transfer data.
I changed the timeout for query and designers so if I execute a query from the view I have no problems but but this timeout has no effects on the view.
Here is my View:
SELECT dbo.ordiniqdopolib.DATAconsegna, dbo.ordiniqdopolib.Fornitore,
dbo.ordiniqdopolib.HOTEL, dbo.ordiniqdopolib.ORDINE,
dbo.ordiniqdopolib.PRODOTTO, dbo.ordiniqdopolib.NUMEROS,
dbo.ordiniqdopolib.COSTOUNITARIOS, dbo.ordiniqdopolib.COSTOTOTALES,
dbo.ordiniqdopolib.CONSEGNATO, dbo.ordiniqdopolib.IDDOCTRASP,
YEAR(dbo.ordiniqdopolib.DATAconsegna) AS anno, dbo.ordiniqdopolib.napoli,
dbo.ordiniqdopolib.CONTRNAP, dbo.REGDOCT.NDOC,
dbo.ordiniqdopolib.ID, dbo.ordiniqdopolib.UTENZA,
dbo.ordiniqdopolib.COMPPERIODO, dbo.ordiniqdopolib.COMPANNO,
dbo.ordiniqdopolib.dataov
FROM dbo.ordiniqdopolib
INNER JOIN dbo.REGDOCT
ON dbo.ordiniqdopolib.IDDOCTRASP = dbo.REGDOCT.ID
WHERE (dbo.ordiniqdopolib.Fornitore <> 'Inventario Napoli') AND
(dbo.ordiniqdopolib.ORDINE > 0) AND
((dbo.ordiniqdopolib.CONSEGNATO = - 1) OR (dbo.ordiniqdopolib.ORDINE < 0)) AND
(dbo.ordiniqdopolib.CONTRNAP = 0)
Any suggestions on how to avoid the 30-second timeout?

Want to occur deadlock using sql query

I want to demonstrate a deadlock situation:
In my first transaction:
UPDATE POSITION SET EXTRA = EXTRA || 'yes' WHERE NAME="JOHN"
UPDATE POSITION SET EXTRA = 'HI' WHERE EXTRA = 'EXTRA';
So second transaction:
UPDATE POSITION SET BONUS = BONUS * 1.05;
UPDATE POSITION SET BONUS = 0 IF BONUS IS NULL;
So isn't possible to occur deadlock here just want to try and understand for it
for my knowledge. deadlock occur if update at different row but not different column and transaction occur same with each other, but for this 4 updates. i don't know how to make it become deadlock situation
Deadlocks occur when two processes block each other by trying to obtain the same resources in a different order. I've seen Oracle deadlocks happen for three reasons, there are probably more:
Concurrent sessions update the same rows in different order because explain plans retrieve the rows differently. For example, one session uses an index and another uses a full table scan.
Un-indexed foreign keys cause table locks.
Bitmap indexes and any type of concurrent DML on a table.
The code below demonstrates the first case. It generates a deadlock by looping through two of your update statements. The index causes the first session to use an INDEX RANGE SCAN and the second session uses a FULL TABLE SCAN. The results are not deterministic but it only took about a second for this to fail on my PC.
Sample schema and data
create table position(name varchar2(100), extra varchar2(4000), bonus number);
insert into position select 'JOHN', null, 1 from dual connect by level <= 100;
insert into position select level , null, 1 from dual connect by level <= 100000;
create index position_index on position(name);
Session 1 (run at the same time as session 2)
begin
for i in 1 .. 1000 loop
UPDATE POSITION SET EXTRA = EXTRA || 'yes' WHERE NAME='JOHN';
commit;
end loop;
end;
/
Session 2 (run at the same time as session 1)
begin
for i in 1 .. 1000 loop
UPDATE POSITION SET BONUS = BONUS * 1.05;
commit;
end loop;
end;
/
Error message
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
ORA-06512: at line 3
Find the location of the trace file generated for each deadlock:
select value from v$parameter where name like 'background_dump_dest';
Example of a trace:
...
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-0009000F-00004ACC-00000000-00000000 37 129 X 55 375 X
TX-0008001B-0000489C-00000000-00000000 55 375 X 37 129 X
session 129: DID 0001-0025-00000281 session 375: DID 0001-0037-00012A2C
session 375: DID 0001-0037-00012A2C session 129: DID 0001-0025-00000281
Rows waited on:
Session 129: obj - rowid = 0001AC1C - AAAawcAAGAAAudMAAQ
(dictionary objn - 109596, file - 6, block - 190284, slot - 16)
Session 375: obj - rowid = 0001AC1C - AAAawcAAGAAAudMAAL
(dictionary objn - 109596, file - 6, block - 190284, slot - 11)
----- Information for the OTHER waiting sessions -----
Session 375:
sid: 375 ser: 10033 audsid: 56764801 user: 111/xxxxxxxxxxxx
flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
flags2: (0x40009) -/-/INC
pid: 55 O/S info: user: oracle, term: xxxxxxxxxx, ospid: 7820
image: ORACLE.EXE (SHAD)
client details:
O/S info: user: xxxxxxxxxx\xxxxxxxxxx, term: xxxxxxxxxx, ospid: 11848:10888
machine: xxxxxxxxxx\xxxxxxxxxx program: sqlplus.exe
application name: SQL*Plus, hash value=3669949024
current SQL:
UPDATE POSITION SET BONUS = BONUS * 1.05
----- End of information for the OTHER waiting sessions -----
Information for THIS session:
----- Current SQL Statement for this session (sql_id=cp515bpfsjd07) -----
UPDATE POSITION SET EXTRA = EXTRA || 'yes' WHERE NAME='JOHN'
...
The locked object is not always the table directly modified. Check which object caused the problem:
select * from dba_objects where object_id = 109596;

apache derby hangs up executing query

i'd really appreciate some help here.
I've got this derby database from my customer, and their application based on Hibernate. I can't make it work because Hibernate generates query that hangs up the whole database:
select houses0_.STREET_ID as STREET5_1_, houses0_.ID as ID1_, houses0_.ID as ID42_0_, houses0_.NAME as NAME42_0_, houses0_.SHORT_NAME as SHORT3_42_0_, houses0_.INDEX as INDEX42_0_ from SRG.HOUSE_REFERENCE houses0_ where houses0_.STREET_ID in (select streets0_.ID from SRG.STREET_REFERENCE streets0_ where streets0_.TOWNSHIP_ID in (select townships0_.ID from SRG.TOWNSHIP_REFERENCE townships0_ where townships0_.CITY_ID='555'))
I dont see anything suspicious in it, but when i launch derby with it - derby just does nothing. Here are my logs:
2011-10-31 21:58:10.328 GMT Thread[DRDAConnThread_3,5,main] (XID = 1152939), (SESSIONID = 1), (DATABASE = dev), (DRDAID = NF000001.FC97-434877518919679629{1}), Begin compiling prepared statement: select houses0_.STREET_ID as STREET5_1_, houses0_.ID as ID1_, houses0_.ID as ID42_0_, houses0_.NAME as NAME42_0_, houses0_.SHORT_NAME as SHORT3_42_0_, houses0_.INDEX as INDEX42_0_ from HOUSE_REFERENCE houses0_ where houses0_.STREET_ID in (select streets0_.ID from STREET_REFERENCE streets0_ where streets0_.TOWNSHIP_ID in (select townships0_.ID from TOWNSHIP_REFERENCE townships0_ where townships0_.CITY_ID='555')) :End prepared statement
2011-10-31 21:58:10.682 GMT Thread[DRDAConnThread_3,5,main] (XID = 1152939), (SESSIONID = 1), (DATABASE = dev), (DRDAID = NF000001.FC97-434877518919679629{1}), End compiling prepared statement: select houses0_.STREET_ID as STREET5_1_, houses0_.ID as ID1_, houses0_.ID as ID42_0_, houses0_.NAME as NAME42_0_, houses0_.SHORT_NAME as SHORT3_42_0_, houses0_.INDEX as INDEX42_0_ from SRG.HOUSE_REFERENCE houses0_ where houses0_.STREET_ID in (select streets0_.ID from SRG.STREET_REFERENCE streets0_ where streets0_.TOWNSHIP_ID in (select townships0_.ID from SRG.TOWNSHIP_REFERENCE townships0_ where townships0_.CITY_ID='555')) :End prepared statement
2011-10-31 21:58:10.758 GMT Thread[DRDAConnThread_3,5,main] (XID = 1152939), (SESSIONID = 1), (DATABASE = dev), (DRDAID = NF000001.FC97-434877518919679629{1}), Executing prepared statement: select houses0_.STREET_ID as STREET5_1_, houses0_.ID as ID1_, houses0_.ID as ID42_0_, houses0_.NAME as NAME42_0_, houses0_.SHORT_NAME as SHORT3_42_0_, houses0_.INDEX as INDEX42_0_ from SRG.HOUSE_REFERENCE houses0_ where houses0_.STREET_ID in (select streets0_.ID from SRG.STREET_REFERENCE streets0_ where streets0_.TOWNSHIP_ID in (select townships0_.ID from SRG.TOWNSHIP_REFERENCE townships0_ where townships0_.CITY_ID='555')) :End prepared statement
And NOTHING after that.
I've set some properties:
derby.drda.portNumber=1529
derby.locks.deadlockTrace=true
derby.locks.monitor=true
derby.locks.deadlockTimeout=1
derby.locks.waitTimeout=1
derby.language.logStatementText=false
derby.infolog.append=true
derby.stream.error.logSeverityLevel=0
derby.drda.logConnections=true
derby.language.logStatementText=true
derby.language.logQueryPlan=true
to see whats going on, but there's nothing in logs, this query just takes eternity to execute, either its done from hibernate or squirrelsql or derby's ij tool.
As you can see timeouts are pretty small but derby doesnt stop executing query, it leaves it to do whatever the query wants.
Query is not that complex - i rewrote it using joins and it took 1 sec to execute. But not in that form - i dont get it, why? Can you give me any hints?
UPD: house_reference contains 7508 rows, selecting * from house_reference takes less than a second, street_reference contains ~44k rows, and subquery
select streets0_.ID from STREET_REFERENCE streets0_ where streets0_.TOWNSHIP_ID in (select townships0_.ID from TOWNSHIP_REFERENCE townships0_ where townships0_.CITY_ID='52000001000')
returns 111 rows in less than a second. so selecting * from house_reference with in clause containing 111 rows takes 22 minutes to execute, and it returns 0 results. That doesnt look ok to me, but im not that experienced in database administration to judge, thats why im asking the community :)
Queries specifying "in (subquery)" cannot always be replaced with a corresponding join. This process is called "flattening", and there are rules that the database has to follow in order to give the right answer. See this documentation: http://db.apache.org/derby/docs/10.8/tuning/ctuntransform36368.html
Unfortunately it's not uncommon to have significant performance problems with subqueries in joins. I'm glad you found a workaround (assuming that your re-written query is actually an acceptable workaround for you).
Object-relational mapping libraries can generate some complex queries. If you can get the query to eventually run, you may be able to learn something from the query plan.
Another possibility is that the database statistics have become inaccurate, causing Derby to choose a poor query plan. Recent versions of Derby have improved support for re-computing the statistics, which can help the optimizer choose a better query plan.
There is a wealth of information in the Derby Tuning guide at http://db.apache.org/derby/docs/10.8/tuning/index.html