Kai


  • 首页

  • 关于

  • 标签

  • 归档

MySQL行锁定测试

发表于 2019-08-26 | 分类于 MySQL
1
2
3
4
5
6
7
##准备测试数据
create table locktest(id int primary key,col1 int,index(col1));
insert into locktest values(1,10);
insert into locktest values(2,20);
insert into locktest values(3,30);
insert into locktest values(4,40);
insert into locktest values(5,50);

非唯一索引

范围查询,临键锁(一)

举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#事务A
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from locktest where col1 > 30 and col1 < 50 for update;
+----+------+
| id | col1 |
+----+------+
| 4 | 40 |
+----+------+
1 row in set (0.00 sec)
#事务B
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from locktest;
+----+------+
| id | col1 |
+----+------+
| 1 | 10 |
| 2 | 20 |
| 4 | 40 |
| 5 | 50 |
+----+------+
4 rows in set (0.01 sec)

##col1为20时插入,发生阻塞,插入失败
mysql> insert into locktest(id,col1) values(16,20);
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted

##col1为30时插入,发生阻塞,插入失败
mysql> insert into locktest(id,col1) values(16,30);
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted

##col1为49时插入,发生阻塞,插入失败
mysql> insert into locktest(id,col1) values(16,49);
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted

##col1为50时插入,没有发生阻塞,插入成功
mysql> insert into locktest(id,col1) values(16,50);
Query OK, 1 row affected (0.00 sec)

##col1为51时插入,没有发生阻塞,插入成功
mysql> insert into locktest(id,col1) values(18,51);
Query OK, 1 row affected (0.00 sec)

##col1为19时插入,没有发生阻塞,插入成功
mysql> insert into locktest(id,col1) values(17,19);
Query OK, 1 row affected (0.00 sec)

##col1为20时更新,没有发生阻塞,更新成功
mysql> update locktest set col1=20 where col1=20;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0

##col1为40时更新,发生阻塞,更新失败
mysql> update locktest set col1=40 where col1=40;
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted

##col1为50时更新,发生阻塞,更新失败
mysql> update locktest set col1=50 where col1=50;
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted

结论

列 值
数据(col1) 10、20、40、50
查询条件 > 30 and < 50
锁类型 临键锁
加锁区间 (20,40]、(40,50]
记录锁 40,50
阅读全文 »

MySQL锁机制

发表于 2019-08-25 | 分类于 MySQL

共享锁

共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。
如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获得共享锁的事务只能读数据,不能修改数据。

使用方式:在需要执行的语句后面加上 lock in share mode

排他锁

排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。排它锁是悲观锁的一种实现。
排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。mysql InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁。
select语句默认不会加任何锁类型,加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。
若事务 1 对数据对象A加上X锁,事务 1 可以读A也可以修改A,其他事务不能再对A加任何锁,直到事物 1 释放A上的锁。这保证了其他事务在事物 1 释放A上的锁之前不能再读取和修改A。排它锁会阻塞所有的排它锁和共享锁。

使用方式:在需要执行的语句后面加上for update
阅读全文 »

Redis常用命令

发表于 2019-02-18 | 分类于 Redis

Redis支持五种数据类型:字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(sorted set)。

每一种数据类型所对应的操作命令不同,当然也存在一些通用的,而且Redis的所有命令有很多,本文中记录的都是日常使用频率相对多一些的。

通用命令:

1
2
3
4
5
6
7
8
keys:遍历所有key【O(n)】
dbsize:计算key的总数【O(1)】
exists:检查key是否存在;返回(integer) 1或(integer) 0【O(1)】
del:删除指定的key-value【O(1)】
expire:给key设置过期时间,在seconds秒后过期【O(1)】
ttl:查看可以剩余的过期时间 ;返回(integer) -1:key存在但没有过期时间,(integer) -2 :key不存在【O(1)】
persist:去掉key的过期时间【O(1)】
type:返回key的类型【O(1)】

O(n)代表时间复杂度比较高,不建议在线上使用,O(1)代表时间复杂度较低,可以任意使用

阅读全文 »

PHP写时复制 Copy On Write

发表于 2019-02-17 | 分类于 PHP

写时复制Copy on Write,也缩写为COW。

优点:省去了分配内存和管理内存地址的计算开销, 减少资源的占用

COW是常用的优化手段,可以归类于:资源延迟分配。只有在真正需要使用资源时才占用资源, 写时复制通常能减少资源的占用。

关于内存使用情况,可以使用php函数:memory_get_usage() 来进行查看

例子:

1
2
3
4
5
6
7
8
9
10
11
<?php
$a = range(0,1000);
//系统会给$a开辟一块内存空间
var_dump(memory_get_usage());
$b = $a;
//此时$b也指向了$a的空间,两个变量共用一块内存空间
var_dump(memory_get_usage());
$a = range(0, 1000);
//此时如果对$a或$b进行写操作时(不管值是否发生变化),会再拷贝一份新的空间出来
var_dump(memory_get_usage());
?>

1
2
3
4
执行结果为:
int(455664)
int(455696)
int(525384)

通过结果可以看出来,拷贝出新的内存空间后,内存占用量明显增加。

mysql设置数据库只读权限

发表于 2019-01-15 | 分类于 MySQL

可以理解为开设一个账号,权限为只读

创建并授权用户

1
GRANT select ON *.* to 'test_readonly'@'localhost' identified by '1234';

不必先insert into user…以后再进行授权,以上语句是创建用户的同时并且已授权

PHP魔术常量

发表于 2018-12-30 | 分类于 PHP

1、__METHOD__:返回所在类的方法的名称。与__FUNCTION__不用的是,__METHOD__返回的是”class::function”的形式,而__FUNCTION__返回”function”的形式。
2、__FILE__: 返回当前文件的完整路径。
3、__FUNCTION__:返回所在函数的名字。
4、__LINE__:返回文件中当前的行号。
5、__CLASS__:返回所在类的名字。
6、__DIR__:返回文件所在目录,如果用在被包含文件中,则返回被包含的文件所在的目录
7、__NAMESPACE__:返回当前命名空间的名称(区分大小写)。此常量是在编译时定义的。
8、__TRAIT__:返回Trait被定义时的名字。Trait名包含其被声明的作用区域。

一台mysql服务器启动多个端口

发表于 2018-08-07 | 分类于 MySQL

一、首先要先把my.cnf配置文件复制一份,开几个端口要复制几份,并且要重新命名。

cp /etc/my.cnf /etc/my3307.cnf

二、 修改/etc/my3307.cnf 配置文件

1
2
3
4
5
6
7
8
9
10
11
[client]
port = 3307
socket = /tmp/mysql3307.sock
default-character-set=UTF
[mysqld]
user = root
port = 3307
basedir = /alidata/server/mysql
datadir = /alidata/server/mysql3307/data
socket = /tmp/mysql3307.sock
log-error=/alidata/log/mysql3307/error.log

三、创建数据库指定存放数据的目录

1
mkdir /alidata/server/mysql3307/data

四、创建log日志存放目录

1
mkdir /alidata/log/mysql3307/
阅读全文 »

ssh登录免密码

发表于 2018-08-05

A机器访问B机器无需密码登录

A机器:

cd ~/.ssh
ssh-keygen -t rsa

B机器:

cd ~/.ssh
vi authorized_keys  将A机器~/.ssh/id_rsa.pub文件中的内容复制过来

做完以上操作后,A服务器登陆B服务器时无需密码

阅读全文 »

从这里开始

发表于 2018-08-01

工作的时间不算短了,但其实想想对于业务和技术并没有非常系统的整理,比较碎片化,平日里遇到的一些问题和解决方案没有完全落实到纸面上,有时觉得记忆力还可以…但是终归好记性不如烂笔头,还是决定通过blog方式进行梳理和归纳,将这几年积累的下来经验和技术做一个很好的沉淀,也以此督促自己,不断的扩充自己的知识点,建立良好的技术体系。在这里会记录一些技术知识、心得感想等等。

嗯,就从这里开始。

12
Kai

Kai

随笔记录

19 日志
9 分类
12 标签
© 2022 Kai
由 Hexo 强力驱动
|
主题 — NexT.Gemini