LOCK_TIMEOUT最后是什么时期?
我在登录后执行一个SET LOCK_TIMEOUT 10和SELECT @@LOCK_TIMEOUT一个命令并返回 10。在此之后,我立即SELECT @@LOCK_TIMEOUT再次执行 a并返回 -1。我会认为它仍然是10。
我在 MSDN 站点上做了一些查找,但找不到LOCK_TIMEOUT是基于会话还是基于语句。
我希望能够锁定一行,选择它,增加它的值,然后释放锁定。(不锁定其他行,以便其他连接可以与表的其余部分一起使用)
我找到了这个
BEGIN TRAN SELECT * FROM tablename WITH (HOLDLOCK, ROWLOCK)
WHERE ID = 1
Run Code Online (Sandbox Code Playgroud)
我的问题是我做不到
UPDATE tablename
SET columnName = -1
WHERE ID = 2
Run Code Online (Sandbox Code Playgroud)
在我提交上一个事务之前,为什么行锁会锁定整个表?
编辑:
此代码是否保证在此更新命令期间不会更新所选行的数据?
UPDATE [tablename] WITH (ROWLOCK)
SET columnName = columnName + 5
WHERE ID = 1
Run Code Online (Sandbox Code Playgroud) 我在 MySQL 5.5(Windows XP x64)上有一个很大的 MyISAM 表,我必须在上面运行DELETE LOW_PRIORITY查询。当没有客户端访问表时,是否立即DELETE LOW_PRIORITY使SELECT语句对语句不可见并实际从磁盘中删除行,或者是否延迟删除可见性?
我试图让我的表使用行锁。我已经禁用了锁升级。隔离级别为READ_COMMITTED_SNAPSHOT
alter table <TABLE_NAME> SET (LOCK_ESCALATION=DISABLE)
go
alter index <INDEX_NAME> ON <TABLE_NAME> SET (ALLOW_PAGE_LOCKS=OFF)
go
Run Code Online (Sandbox Code Playgroud)
设置后还是不行。
我是否需要重建我的表以使其不使用页面锁定?
sql-server deadlock sql-server-2008-r2 locking isolation-level
这是一个非常复杂的场景,但我认为最先进的挑战可能会对 dba.se 的许多高端用户感兴趣。
问题
我正在使用 Oracle GoldenGate 为文档生产系统开发洲际数据复制解决方案,有点类似于 wiki。主要目标是在全球范围内提高应用程序性能和可用性。
该解决方案必须允许从多个位置同时读/写访问同一个数据池,这意味着我们需要一些聪明的方法来防止或解决没有用户交互的冲突更新。
专注于碰撞预防,我们必须允许全局锁定对象(文档、插图、一组元数据等),从而防止多个用户同时编辑来自不同位置的同一对象 - 最终导致冲突。
类似地,对象必须保持锁定状态,直到任何用户连接的数据库收到该对象的更新数据,否则用户可能会开始编辑没有最新更新的旧对象。
背景
该应用程序对延迟有些敏感,这使得从远程位置访问中央数据中心的速度变慢。像许多以内容为中心的系统一样,读/写比率在 4 比 1 的范围内,使其成为分布式架构的理想选择。如果管理得当,后者还将努力确保站点或网络中断期间的可用性。
我使用了一种有点非常规的多循环双向复制拓扑。这将复杂性保持在可管理的级别 { 2(n-1) 方式},增加了站点中断的弹性,并允许相当简单地添加或删除站点。一个小缺点是,通过中央主数据库在最远程站点之间复制事务可能需要长达 30 秒的时间。
在所有站点之间直接复制的更传统的设计会将时间缩短一半,但也会显着增加配置 { n(n-1) 方式}的复杂性。
五个位置意味着 20 路复制,而不是我设计中的 8 路复制。
此图显示了我当前跨欧洲、亚洲和北美数据中心的测试环境。生产环境预计会有更多的位置。

所有数据库都是 Oracle 11.2.0.3 和 Oracle GoldenGate 11.2.1。
到目前为止我的想法
我一直在思考通过在中央数据库的数据库链接上将一行插入到“锁定”表中来进行锁定,同时让解锁(前面提到的行的更新或删除)与更新的行一起复制数据。
在获取锁和打开对象进行编辑之前,我们必须代表用户检查中央和本地数据库中锁的可用性。编辑完成后,我们必须释放本地数据库中的锁,然后通过中央数据库将更改和锁的释放复制到所有其他位置。
但是,对高延迟数据库链接的查询有时会非常慢(测试显示单个插入需要 1.5 秒到 7 秒),而且我不确定我们是否可以保证删除锁的更新或删除语句是要复制的最后一条语句。
调用远程 PL/SQL 过程进行检查和锁定至少会将操作限制为单个远程查询,但 7 秒仍然是很长的时间。像两秒钟这样的事情会更容易接受。我希望可以以某种方式优化数据库链接。
还可能存在其他问题,例如在从中央数据库成功复制本地锁定表中的行之前尝试删除或更新该行。
从好的方面来说,使用这种解决方案,如果与中央数据库的通信中断,让应用程序进入只读状态,或者在数据中心不可用时重定向客户端,应该相对简单。
有没有人做过类似的事情?解决这个问题的最佳方法是什么?
就像我最初说的那样,这是一个相当复杂的解决方案,请随时询问任何不清楚或遗漏的地方。
我有一些许多用户需要访问的表:
mysql> show create table v3_cam_date\G
*************************** 1. row ***************************
Table: v3_cam_date
Create Table: CREATE TABLE `v3_cam_date` (
`campaignid` mediumint(9) NOT NULL DEFAULT '0',
`totalclick` mediumint(9) unsigned NOT NULL DEFAULT '0',
`totalview` int(11) unsigned NOT NULL DEFAULT '0',
`realclick` mediumint(9) unsigned NOT NULL DEFAULT '0',
`clickcharge` mediumint(9) unsigned NOT NULL DEFAULT '0',
`viewcharge` int(11) unsigned NOT NULL DEFAULT '0',
`uv` mediumint(9) unsigned NOT NULL DEFAULT '0',
`uc` mediumint(9) unsigned NOT NULL DEFAULT '0',
`dt` date NOT NULL DEFAULT '0000-00-00',
`ctr` …Run Code Online (Sandbox Code Playgroud) 我有一个带有 PK 和唯一非聚集索引的表,如下所示:
CREATE TABLE Table1
(
Id INT IDENTITY(1,1) NOT NULL,
Field1 VARCHAR(25) NOT NULL,
Field2 VARCHAR(25) NULL,
CONSTRAINT PK_Table1 PRIMARY KEY CLUSTERED (Id ASC)
)
CREATE UNIQUE NONCLUSTERED INDEX IX_Field1_Field2 ON Table1
(
Field1 ASC,
Field2 ASC
)
WITH
(
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF,
DROP_EXISTING = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
)
Run Code Online (Sandbox Code Playgroud)
我有 2 个工作,我发现它们的执行时间相互重叠。它们都将相同的内容包含在INSERT此表中,并且最后开始的作业经常失败,因为它尝试将记录插入到Table1具有重复索引键值的中。
INSERT Table1
SELECT Field1, Field2
FROM …Run Code Online (Sandbox Code Playgroud) 我正在处理一个死锁问题。
进程 A 正在对 TableA 执行简单的 INSERT,它对 TableB 有一个 FK
进程 B 正在对包含 TableA 和 TableB 的连接执行复杂的 SELECT
我将在下面包含跟踪信息,但基本上我认为正在发生的是由于 TableA 对 TableB 具有 FK,因此对 TableA 的插入导致了 TableB 的 Primany INDEX 上的排他锁 (X)。我们确实为那个 FK 启用了参照完整性,但是不需要通过插入到 TableA 来更新 TableB,所以我觉得奇怪的是,只需要一个排他锁来检查 FK 值的存在。
这是预期的行为吗?如果是这样,我可以做些什么来减轻这种情况?老实说,我没想到这样一个基本/香草插入会导致僵局。
此外,这不是我真正的问题,但如果您碰巧知道“子资源=满”意味着什么,我会很想知道。
编辑:只是要清楚僵局:
processInserting 正在插入到 TableA 并且在 TableB 上的主索引(TableA 的外键)上有一个 X 锁。ProcessSelecting 正在等待对该索引的 RangeS-S 锁定。
processSelecting 从包括 TableA 和 TableB 在内的许多表的连接中进行选择,并且在 TableA 上有一个 S 锁(因为它正在连接它)。ProcessInserting 正在等待此表上的 IX 锁。
编辑 2:提供更多细节。我正在调用 processSelecting 的“选择”查询是一个非常折磨人的查询,它使用一个折磨人的视图作为连接的一部分,所以看起来有点混乱。
这是 RoutePlan (TableA) 和 Form (TableB) 表的 DDL。
正如在stackoverflow 上被问到的那样,但是对于 MySQL,我想知道它在 PostgreSQL 中是如何工作的。当我将“FOR UPDATE”与“LIMIT”、“ORDER BY”和一些“WHERE”组合在一起时,锁定了多少行。他们更新返回的行。我希望“FOR UPDATE”查询只会锁定一行,但也许我错过了一些实现问题。(我打算写一些压力测试来更可靠地重现这一点)
这些查询导致我的系统出现死锁:
(session1) select field1, field2, ... from documents where transaction_path='some/path' for update
(session2) select field1, field2, ... from documents where (transaction_path is null) and queue_id=2 and next_pickup_ts<now() order by next_pickup_ts limit 1 for update
(session3) select field1, field2, ... from documents where (transaction_path is null) and queue_id=2 and next_pickup_ts<now() order by next_pickup_ts limit 1 for update
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么。(transaction_path 上有一个唯一索引。)
在我粗略的研究过程中,我无法找到有关SELECT INTO OUTFILE超过INSERT INTO ... SELECT. 在阅读与InnoDB 表上的相关锁相关的文档时,INSERT INTO ... SELECT它指出:
在插入到 T 的每一行上设置一个没有间隙锁的排他索引记录。 如果事务隔离级别为 READ COMMITTED 或启用了 innodb_locks_unsafe_for_binlog,并且事务隔离级别不是 SERIALIZABLE,则 InnoDB 将 S 上的搜索作为一致读(不锁)。否则,InnoDB 会在来自 S 的行上设置共享的 next-key 锁。
为了避免锁定INSERT INTO ... SELECT似乎我必须确保隔离级别是READ COMMITTED为了避免在查询过程中锁定源表。
但是,我无法找到任何有关锁和使用的权威答案SELECT INTO OUTFILE,甚至没有找到MySQL文档参考锁信息。
我的目标是避免在查询运行时锁定源表以避免连接堆叠。
locking ×10
sql-server ×4
deadlock ×3
innodb ×2
mysql ×2
alter-table ×1
delete ×1
foreign-key ×1
goldengate ×1
mysql-5.5 ×1
oracle ×1
partitioning ×1
postgresql ×1
replication ×1