删除 LOW_PRIORITY 行可见性

nan*_*rad 6 delete mysql-5.5 locking

我在 MySQL 5.5(Windows XP x64)上有一个很大的 MyISAM 表,我必须在上面运行DELETE LOW_PRIORITY查询。当没有客户端访问表时,是否立即DELETE LOW_PRIORITY使SELECT语句对语句不可见并实际从磁盘中删除行,或者是否延迟删除可见性?

Der*_*ney 5

文档

如果您指定 LOW_PRIORITY,服务器会延迟 DELETE 的执行,直到没有其他客户端从表中读取。这仅影响仅使用表级锁定的存储引擎。

所有这一切意味着DELETE LOW_PRIORITY语句在所有读锁完成之前不会开始处理。如果另一个读锁在DELETE LOW_PRIORITY语句开始之前进入,它将等待。

一旦DELETE LOW_PRIORITY语句获得锁,它将获取表锁并运行直到完成(或被杀死)。

在正常的表锁定情况下,任何写请求都将比读请求获得更高的优先级。例子:如果你有一个写锁,然后一个读请求进入读队列,然后另一个写请求进来,第二个写请求将在读请求之前执行。

使用LOW_PRIORITY,情况正好相反。如果读锁正在进行,并且写进来,它将等待。如果在写入获得锁定之前另一个读取进入,则第二次读取将执行并且写入将等待。

因此,如果您DELETE LOW_PRIORITY在经常读取的表上使用,则该DELETE LOW_PRIORITY语句可能会等待很长时间。

一旦在表锁定情况下获得了写锁,任何读取都将在队列中等待,直到写锁完成。


Jac*_*las 4

行仍然可见。测试 (1) 显示这delete不会阻止任何行对后续查询可见。测试 (2) 说明了正常情况下立即获取的表锁delete- 查询等待直到delete完成并返回零计数。

测试台和长时间运行的查询:

create database stack;
use stack;
--
create table my_table (id int auto_increment primary key, varchar_val varchar(10));
insert into my_table (varchar_val)
select 'HELLO'
from (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s1,
     (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s2,
     (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s3,
     (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s4;
--
select avg(t1.id), avg(t2.id), count(*) from my_table t1 cross join my_table t2;
--
Run Code Online (Sandbox Code Playgroud)

测试(1):低优先级:

--session 2:
delete low_priority from stack.my_table;
/*
Query OK, 10000 rows affected (21.84 sec)
*/

--session 3:
select count(*) from stack.my_table;
/*
+----------+
| count(*) |
+----------+
|    10000 |
+----------+
1 row in set (0.00 sec)
*/
Run Code Online (Sandbox Code Playgroud)

测试(2):无low_priority

--session 2:
delete low_priority from stack.my_table;
/*
Query OK, 10000 rows affected (21.15 sec)
*/

--session 3:
select count(*) from stack.my_table;
/*
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (18.10 sec)

*/
Run Code Online (Sandbox Code Playgroud)