我们正在尝试更好地优化我们使用 MongoDB 实例的方式。我们似乎经常获得高锁定百分比,并希望帮助将其最小化。这是一些 mongostat 输出:
insert query update delete getmore command flushes mapped vsize res faults locked % idx miss % qr|qw ar|aw netIn netOut conn time
1 107 186 0 0 196 0 3.06g 7.3g 333m 0 11.2 0 0|0 2|0 66k 224k 85 15:55:22
2 102 285 0 0 296 0 3.06g 7.3g 333m 0 15.7 0 0|0 2|0 89k 216k 84 15:55:23
2 79 325 0 0 335 0 3.06g 7.3g 333m 0 20.2 0 0|0 3|0 …Run Code Online (Sandbox Code Playgroud) 一些上下文:
起初我们只是“直接”编写报告,在查询中没有任何锁定提示。对于较大的报告,这有时会导致锁定问题。在第一,我们通过使用补救这WITH (NOLOCK)提示在查询表。
因为(a)它是相当突兀,和(b)很容易忘记一个表的提示,我们搬到了第二种方法设置TRANSACTION ISOLATION LEVEL到READ UNCOMMITTED每个数据集的查询的顶部(这是罚款)。
正如您可能猜到的,忘记其中一个数据集的提示仍然很容易。所以这就引出了一个问题:
问题:与报告查询一起发送NOLOCK提示的选项有哪些?
附注。我意识到这在某种程度上是一个XY 问题(我对 X 有很多其他选择,例如优化查询,不报告操作数据库等),但仍然试图使其成为一个有效的问题.
选项:
以下是上面提到的选项,添加了一些我很好奇它们是否可行的选项:
WITH (NOLOCK)为每个表设置提示。(突兀,很容易忘记)READ UNCOMMITTED为整个查询设置隔离级别。(还是很容易忘记)哪些选项是可行的?有没有我错过的选项?
我有一个死锁图,其中一个进程正在执行 SELECT 并且一个进程正在执行 UPDATE。这似乎是 SELECT 获取 NCI 锁以执行连接,然后获取 CI 锁以通过查找检索所有数据的经典案例。UPDATE 使用 CI 锁执行更新,然后需要锁定 NCI,因为更新会导致状态更改,并且 NCI 有助于按状态查找项目。
问题是 UPDATE 想要的锁之一不在它正在更新的表上,我找不到为什么会发生这种情况。
这是选择:
SELECT *,
RIGHT(c.CC_NUMBER, 4) AS CC_LAST_4,
DATEDIFF(ss, '1970-01-01', plan_started ) plan_started_epoch,
DATEDIFF(ss, '1970-01-01', plan_expires ) plan_expires_epoch
FROM customers c, accounts a, parent_cos pc, htt_customers_overlay_ultra u
WHERE c.customer_id = a.customer_id
AND u.customer_id = c.customer_id
AND a.cos_id=pc.cos_id
AND u.customer_id = 9300;
Run Code Online (Sandbox Code Playgroud)
这是更新:
UPDATE htt_customers_overlay_ultra SET plan_state = 'Active' WHERE customer_id = 9300;
Run Code Online (Sandbox Code Playgroud)
但是根据死锁图,UPDATE是在ACCOUNTS.ACCOUNT0上获取锁,也就是ACCOUNTS表的PK(CI)。覆盖表中没有外键。有一些我目前无权查看的默认约束。
我查看了 SSMS 和 SQL Sentry Plan Explorer …
我的任务是编写一个更新查询来更新一个包含超过 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) 在我粗略的研究过程中,我无法找到有关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文档参考锁信息。
我的目标是避免在查询运行时锁定源表以避免连接堆叠。
我有一个表继承设置,可以像这样简化:
CREATE TABLE p (
id BIGSERIAL PRIMARY KEY,
type_id BIGINT,
approved BOOLEAN
);
CREATE INDEX ON p(approved);
CREATE TABLE a (
a_field VARCHAR,
PRIMARY KEY (id),
CHECK(type_id = 1::BIGINT)
) INHERITS (p);
CREATE TABLE b (
b_field INT,
PRIMARY KEY (id),
CHECK(type_id = 2::BIGINT)
) INHERITS (p);
CREATE INDEX ON b(approved);
CREATE TABLE c (
c_field NUMERIC,
PRIMARY KEY (id)
-- this table is missing the check constraint (for no good reason)
) INHERITS (p);
Run Code Online (Sandbox Code Playgroud)
我现在有一个锁定 table 的长期运行事务a …
在长时间运行的进程 (90m+) 中,我们的代码调用SELECT RELEASE_LOCK('..');. 但是,Mysql has gone away当我们这样做时,它总是会出现“ ”错误。
我们从来没有看到 ; 的返回值RELEASE_LOCK。查询没有执行。在找到结果之前,我们失去了连接。
我们以前从未遇到过这个问题。这是在 Magento 1.12 升级到 1.13 之后
我们尝试了很多方法,包括增加各种超时,但都无济于事。您可能会建议什么是好的调试策略或可能导致此问题的东西?
我知道视图是使用规则系统实现的,但我不清楚在针对它们运行事务性 DDL 时这是否有任何优点/缺点。发出CREATE OR REPLACE VIEW ...;或DROP VIEW ...; CREATE VIEW...;在事务中是否会针对表取出类似于 DDL的ACCESS EXCLUSIVE锁?所有在 DDL 之前发出的查询都必须在 DDL 执行之前完成吗?查询会在 DDL 阻塞后发出,直到 DDL 完成吗?
我正在使用 Postgres 9.3。
我有 2 个表 :authn_session和customer. 每个都authn_session属于 a customer(因此有 acustomer_id作为列,这是客户的 FK id)。
注意:这些表包含对其他表和索引的额外 FK 引用。
现在,我开始 2 个不同的事务,它们按照下面提到的顺序执行以下操作:
发送:1
BEGIN;
UPDATE customer
SET customer__created_by =
(case when customer__created_by = 1 then 5
else customer__created_by end),
customer__modified_by =
(case when customer__modified_by = 1 then 5
else customer__modified_by end);
UPDATE authn_session
SET authn_session__created_by =
(case when authn_session__created_by = 1 then 5
else authn_session__created_by end),
authn_session__modified_by =
(case when authn_session__modified_by = 1 …Run Code Online (Sandbox Code Playgroud) 我有一个需要执行的命令列表,所有这些命令都包含在我命名为 的表中myQueue。这个表有点独特,因为一些命令应该组合在一起,以便它们的执行按顺序执行,而不是并发执行,因为同时执行它们会导致不需要的数据工件和错误。因此,队列不能以典型的FIFO / LIFO方式分类,因为出队顺序是在运行时确定的。
总结一下:
myQueue将充当命令队列(其中出队顺序在运行时确定)UPDATE而不是 a执行的,DELETE因为此表用于所述命令的历史性能报告我目前的方法是通过sp_getapplock/sp_releaseapplock调用使用显式互斥逻辑来迭代这个表。虽然这按预期工作,但该方法会生成足够的锁定,因此在任何给定时间都无法在队列上迭代大量工作线程。在阅读了 Remus Rusanu关于该主题的优秀博客文章后,我决定尝试使用表格提示,希望可以进一步优化我的方法。
我将包含下面的测试代码,但总结一下我的结果,使用表提示和消除对sp_getapplock/ 的调用的缺点sp_releaseapplock最多会导致以下三种不良行为:
不过,从积极的方面来说,当代码适应死锁时(例如,重试当前包含的违规操作),不使用sp_getapplock/sp_releaseapplock且不会表现出不良行为的方法 2 和 3 的执行速度至少是两倍,如果不是更快的话.
我希望有人会指出我没有正确构建出列语句,这样我仍然可以继续使用表提示。 如果那不起作用,那就这样吧,但我想看看它是否可以做到同样的事情。
可以使用以下代码设置测试。
该myQueue表的创建和人口与命令类似于够我的工作量:
CREATE TABLE myQueue
(
ID INT IDENTITY (1,1) PRIMARY KEY CLUSTERED,
Main INT, …Run Code Online (Sandbox Code Playgroud) locking ×10
sql-server ×4
postgresql ×3
deadlock ×2
mysql ×2
concurrency ×1
connectivity ×1
ddl ×1
innodb ×1
mongodb ×1
mysql-5.5 ×1
partitioning ×1
queue ×1
ssrs ×1
view ×1