我有一个表,用于存储每个大小在 16-100 KB 之间的图像。由于图像太小,我采纳了Microsoft 的建议,没有使用 FILESTREAM 数据类型。该表的构造很简单:
CREATE TABLE Screenshot(
Id bigint NOT NULL,
Data varbinary(max) NOT NULL,
CONSTRAINT PK_Screenshot PRIMARY KEY CLUSTERED
(
Id ASC
)WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
该表被大量插入(过去一周有 200 万条记录)并且很少被选中。关键是使用hilo 算法,因此大多数情况下会在末尾添加新行。
由于锁定和争用,当许多进程尝试插入到该表中时,我一直遇到问题。查询因等待锁定而超时。
我应该将此表迁移到它自己的文件组和驱动器吗?在这种情况下,如何提高插入性能并减少争用?
我是一个偶然的 DBA 并且仍在学习。
当我从 DMV:s 或 Activity Monitor 看到某个进程正在阻塞另一个进程时,应该怎么做?
我应该简单地终止这些进程还是有办法“释放”或者抢占这种阻塞?
MyISAM 存储引擎使用的表级锁定有什么好处?行级锁定有很多好处,比如并发更新和不锁定表的读取。
编辑 人们普遍认为表级锁定可以防止死锁。但是,以并发为代价来防止死锁如何值得呢?
SQL Server 是否有任何简单的方法来获取有关给定查询在执行过程中取出多少(以及可能是什么类型)锁的指标?
基本原理...
我正在重写一个相当讨厌的存储过程,它大量使用游标。基于集合的解决方案是可能的,因此我得到了三个版本:原始版本、带有表变量的基于集合的版本和完全基于 CTE 的基于集合的版本。我正在为基于 CTE 的解决方案获得良好的指标,但由于 CTE 版本创建的查询的大小和复杂性,我对发布它持谨慎态度,直到我对它进行了尽可能多的尽职调查。
现在我意识到 SQL 取出的锁是它认为需要在给定时间点取出的锁,并且在加载的生产服务器上它的行为可能会有所不同,但我希望它能给我一种感觉它会表现。
目前我正在使用探查器并保持事务打开以便我可以运行sp_lock,但想知道我是否遗漏了 SQL Server 2008 中的一个技巧。
或者,我试图说服自己分析器在插入表变量时返回大量读取是可以的(对于给定的值 Ok),但我没有说服自己。CTE 解决方案的读取次数是 table-var 版本的一半,而 table-var 版本的高读取计数似乎完全取决于插入。在持续时间方面,CTE 和表 var one 大致相同,执行时间比基于游标的方法快 150-200%。
有时,我会在我的 PHP 错误日志中发现很多这些错误:
MYSQL.1213: Deadlock found when trying to get lock; try restarting transactionSQL
Run Code Online (Sandbox Code Playgroud)
问题持续约 2 或 3 分钟。感谢stackoverflow,原因很容易找到:
------------------------
LATEST DETECTED DEADLOCK
------------------------
130320 15:53:37
*** (1) TRANSACTION:
TRANSACTION 0 83395751, ACTIVE 35 sec, process no 26405, OS thread id 140507872417536 starting index read
mysql tables in use 3, locked 3
LOCK WAIT 3 lock struct(s), heap size 1216, 2 row lock(s)
MySQL thread id 1163191, query id 199629038 localhost sosci Updating
UPDATE `database`.`table` SET `invalidate`='2013-03-21 03:53:02' …Run Code Online (Sandbox Code Playgroud) 我的任务是编写一个更新查询来更新一个包含超过 8.5 亿行数据的表。以下是表结构:
源表:
CREATE TABLE [dbo].[SourceTable1](
[ProdClassID] [varchar](10) NOT NULL,
[PriceListDate] [varchar](8) NOT NULL,
[PriceListVersion] [smallint] NOT NULL,
[MarketID] [varchar](10) NOT NULL,
[ModelID] [varchar](20) NOT NULL,
[VariantId] [varchar](20) NOT NULL,
[VariantType] [tinyint] NULL,
[Visibility] [tinyint] NULL,
CONSTRAINT [PK_SourceTable1] PRIMARY KEY CLUSTERED
(
[VariantId] ASC,
[ModelID] ASC,
[MarketID] ASC,
[ProdClassID] ASC,
[PriceListDate] ASC,
[PriceListVersion] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
)
CREATE TABLE [dbo].[SourceTable2](
[Id] [uniqueidentifier] …Run Code Online (Sandbox Code Playgroud) 类似问题:Mongodb 上的高全局锁定百分比
我们在 v2.4.8 mongodb 中有一个生产设置副本集,它运行在五个 4 核、28gb RAM 虚拟机上,标准 azure 数据磁盘 HDD 运行在 64 位 CentOS 6 上。我们以大约 600-700 ops/sec/secondary 的速度在辅助节点上分配读取。每个辅助节点的 CPU 使用率约为 15%。主服务器上的 CPU 使用率约为 5-10%。我们目前在我们的主服务器上遇到高全局写锁和后台刷新平均值的问题。尽管每秒只有大约 200 次插入/更新/删除(请参阅下面的 MMS 输出),但我们的主服务器上的全局写锁定在 30-40% 之间。我们还注意到,我们的后台刷新平均值在 2 到 15 秒之间。不幸的是,这会导致大量缓慢的查询(每秒最多 50 次更新/插入 > 100 毫秒)。我们已经考虑过分片,但觉得 mongodb 应该表现得比这更好。
这告诉我,我们在写入 HDD 时遇到问题,但运行一个简单的 iostat 显示我们在 sdc(我们正在写入的磁盘)上的利用率没有达到最大值,并且在 20% 到 40% 之间:
$ iostat -x 1
Run Code Online (Sandbox Code Playgroud)
4秒结果:
Linux 2.6.32-279.14.1.el6.openlogic.x86_64 (mongodb3-wus) 05/08/2014 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
5.28 0.00 1.82 …Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我必须执行分布式锁定模式。因为我们已经有一个 SQL Server 实例可以使用,所以我们决定在我们的 Web 应用程序的 SQL 层实现锁定是最容易的。
可以根据多种条件获得锁,包括:
出于所有意图和目的,将上述两个条件视为int数据类型。
在这种模式中,我们希望将我们所有的锁都视为 FIFO,我相信SERIALIZABLE隔离级别会给我们带来这种好处。
以下是我们建议如何执行“锁定”:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
IF EXISTS (SELECT 1 FROM locks WHERE LockType = @LockType AND ApplicationIdentifier = @ApplicationIdentifier)
BEGIN
-- Awesome, the lock will be acquired
INSERT INTO locks OUTPUT INSERTED.LockId VALUES (2,3)
END
ELSE
BEGIN
-- Someone already has the lock
SELECT -1
END
SET TRANSACTION ISOLATION LEVEL READ COMITTED
Run Code Online (Sandbox Code Playgroud)
和“解锁”:
DELETE FROM locks WHERE LockId = @LockId
Run Code Online (Sandbox Code Playgroud)
所以我的问题有两个方面: …
我们正在运行 Postgres 9.3,偶尔会出现死锁问题。目前有人注意到并将手动终止进程。当它们发生时,是否有处理这些问题的最佳实践?我知道有一个statement_timeout,lock_timeout而deadlock_timeout但大多数地方,我读状态,你不想设置此的postgres.conf文件。
只是想看看是否有典型/最佳实践方法。看起来将 deadlock_timeout 设置为 10 分钟就足够了,但我想确保我没有遗漏一些关键的东西,为什么这会是一个坏主意。
在我工作的项目中,用于选择对象的 sql 总是选择更新,无论上下文是否为事务。
我的问题是它是否有任何风险、性能问题、或导致死锁或其他顽皮的可能性?
我知道 select for update 只能在事务内锁定一行,这是常见的用例。
我提供了以下两个具体用例,无论是否在事务内部,都在选择更新后使用。
book = booksRepository->getBook(7);
return book;
Run Code Online (Sandbox Code Playgroud)
bookRepository->startTransaction();
book = booksRepository->getBook(7);
if (//some condition with the book properties) {
bookRepository->updateBookAuthor(7, 'bbb');
}
bookRepository->commitTransaction();
Run Code Online (Sandbox Code Playgroud)
在上面的两个例子中,存储库中的函数 getBook 确实选择更新
SELECT * FROM BOOKS
WHERE id = :id
FOR UPDATE;
Run Code Online (Sandbox Code Playgroud)
我问了其他开发人员,他们为什么这样做的答案是“因为否则我们将不得不在存储库中创建两个函数,一个 getBook 和一个 getBookForUpdate,所以我们只选择始终进行更新”...
该答案没有为我可以学习的地方提供任何见解或解释,所以我在这里问。
locking ×10
sql-server ×4
deadlock ×3
mysql ×3
innodb ×1
linux ×1
mongodb ×1
myisam ×1
performance ×1
postgresql ×1
select ×1