一、共享锁(S锁)/排他锁(X锁)

事务拿到某一行记录的共享S锁,才可以读取这一行,并阻止别的事物对其添加X锁

事务拿到某一行记录的排它X锁,才可以修改或者删除这一行

共享锁的目的是提高读读并发

排他锁的目的是为了保证数据的一致性

二、意向锁

1、意向共享锁

预示事务有意向对表中的某些行加共享S锁

2、意向排他锁

预示着事务有意向对表中的某些行加排他X锁

3、 IS、S、IX、X锁之间的兼容性比较:

兼容性

IS

IX

S

X

IS

兼容

兼容

兼容

互斥

IX

兼容

兼容

互斥

互斥

S

兼容

互斥

兼容

互斥

X

互斥

互斥

互斥

互斥

4、意向锁的意义在哪里?

1.IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突

2.意向锁是在添加行锁之前添加。

3.如果没有意向锁,当向一个表添加表级X锁时,就需要遍历整张表来判断是否存行锁,以免发生冲突

4.如果有了意向锁,只需要判断该意向锁与表级锁是否兼容即可。

三、插入意向锁(insert intention looks)

插入意向锁是间隙锁的一种,针对insert操作产生。

目的是提高插入并发。

多个事物,在同一个索引,同一个范围区间进行插入记录的时候,如果 插入的位置不冲突,不会阻塞彼此。

示例:

t1(id primary key,id1 int)

mysql> select * from t1;

+----+------+

| id | id1 |

+----+------+

| 10 | 10 |

| 20 | 20 |

| 30 | 30 |

+----+------+

3 rows in set (0.00 sec)

mysql> start transaction; mysql> start transaction;

Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values(11,11); mysql> insert into t1 values(12,12);

Query OK, 1 row affected (0.00 sec) Query OK, 1 row affected (0.00 sec)

mysql> select * from t1; mysql> select * from t1;

+----+------+ +----+------+

| id | id1 | | id | id1 |

+----+------+ +----+------+

| 10 | 10 | | 10 | 10 |

| 11 | 11 | | 12 | 12 |

| 20 | 20 | | 20 | 20 |

| 30 | 30 | | 30 | 30 |

+----+------+ +----+------+

4 rows in set (0.00 sec) 4 rows in set (0.00 sec)

由于事物一和事物二都是对表的同一索引范围进行insert,使用的插入意向锁,由于插入的记录并不冲突,所以并不会阻塞事物二。如果事物二插入的记录与事物一冲突,会被X锁阻塞。

四、记录锁

对单条索引记录进行加锁,锁住的是索引记录而非记录本身,即使表中没有任何索引,MySQL会自动创建一个隐式的row_id作为聚集索引来进行加锁。

t1(id int primary key,id1 int)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1 where id=20 for update; //记录锁,锁住id=20

+----+------+

| id | id1 |

+----+------+

| 20 | 20 |

+----+------+

1 row in set (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> update t1 set id1=200 where id=20; //被hang住

五、间隙锁(gap锁)

封锁记录中的间隔,防止间隔中被其他事务插入。

间隙锁主要出现在RR隔离级别,避免出现幻读。

1、MVCC(多版本并发)

1.MVCC的作用

避免脏读、写不阻塞读、实现可重复读、多版本控制

2.在MVCC下,读操作可以分为两种:快照读、当前读

1)快照读

select * from tbl_name where ...

2)当前读

select * from tbl_name where ... for update;

update

delete

insert

3)为什么delete/update也是一种当前读?(如一个update操作)

a.在进行update的时候,MySQL会根据where条件得到过滤出来的第一条记录,并进行加锁(currenet read)

b.对该条记录进行update

c.再次读取下一条记录,直到没有满足条件的记录为止

d.delete原理与之类似

4)为什么insert也是一种当前读?

insert操作可能会触发Unique Key的冲突检查,也会进行一个当前读。

2、隔离级别

1.Read Uncommitted

可以读取到未提交的事物

2.Rrad Committed(RC)

针对当前读,RC隔离级别保证对读取到的记录加锁 (记录锁),存在幻读现象。

3.Repeatable Read (RR)

针对当前读,RR隔离级别保证对读取到的记录加锁 (记录锁),同时保证对读取的范围加锁,新的满足查询条件的记录不能够插入 (间隙锁),不存在幻读现象。

4.Serializable

所有的读操作均为当前读,读加读锁 (S锁),写加写锁 (X锁)。

读写冲突,并发行很差

3、几种触发间隙锁的情况

1.id非唯一索引+RR

SQL:delete from t1 where id = 10;

加锁流程如下:

a.通过id索引定位到第一条满足查询条件的记录,加记录上的X锁,加GAP上的GAP锁,

b.然后加主键聚簇索引上的记录X锁,然后返回;

c.然后读取下一条,重复进行。

d.直至进行到第一条不满足条件的记录[11,f],此时,不需要加记录X锁,但是仍旧需要加GAP锁,最后返回结束。

2.id无索引+RR

SQL:delete from t1 where id = 10;

加锁流程如下:

a.由于id字段无索引,进行全表扫描的当前读,

b.聚簇索引上的所有记录,都被加上了X锁。其次,聚簇索引每条记录间的间隙都被加上了GAP锁。

3.针对id无索引+RR MySQL性能上做的一些优化

semi-consistent read

semi-consistent read开启的情况下,对于不满足查询条件的记录,MySQL会提前放锁。

针对上面的这个用例,就是除了记录[d,10],[g,10]之外,所有的记录锁都会被释放,同时不加GAP锁。

4.semi-consistent read如何触发?

1)隔离级别是read committed;

2)隔离级别是Repeatable Read,同时设置了 innodb_locks_unsafe_for_binlog 参数。

示例一:非唯一索引 + 等值当前读

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> delete from t2 where myid = 100;

Query OK, 2 rows affected (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t2 values(3,98);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(134,98);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(7,104);

ERROR 1062 (23000): Duplicate entry '7' for key 'PRIMARY'

mysql> insert into t2 values(8,104);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(118,104);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(118,105);

Query OK, 1 row affected (0.00 sec)

示例二:非唯一索引 + 范围当前读

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t2 where myid > 100 for update;

+-----+------+

| id | myid |

+-----+------+

| 98 | 105 |

| 123 | 109 |

+-----+------+

2 rows in set (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t2 values(8,100);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(4,100);

Query OK, 1 row affected (0.00 sec)

mysql> insert into t2 values(3,101);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(99,101);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(99,108);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(134,128);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

示例三:主键索引 + 范围当前读

mysql> select * from t2 where id > 100 for update;

+-----+------+

| id | myid |

+-----+------+

| 123 | 109 |

| 999 | 56 |

+-----+------+

2 rows in set (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t2 values(99,192);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(125,192);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> insert into t2 values(1259,192);

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> select * from t2 where id=123 lock in share mode;

^C^C -- query aborted

ERROR 1317 (70100): Query execution was interrupted

mysql> select * from t2 where id=124 lock in share mode;

Empty set (0.00 sec)

六、临键锁(Next-Key Locks)

临键锁是记录锁和间隙锁的组合,既锁住了记录也锁住了范围。

临键锁的主要目的,也是为了避免幻读。

如果把事务的隔离级别降级为RC,临键锁就也会失效。

通常情况下,InnoDB在搜索或扫描索引的行锁机制中使用“临键锁(next-key locking)”算法来锁定某索引记录及其前部的间隙(gap),以阻塞其它用户紧跟在该索引记录之前插入其它索引记录。

innodb_locks_unsafe_for_binlog默认为OFF,意为禁止使用非安全锁,也即启用间隙锁功能。将其设定为ON表示禁止锁定索引记录前的间隙,也即禁用间隙锁,InnoDB仅使用索引记录锁(index-record lock)进行索引搜索或扫描,不过,这并不禁止InnoDB在执行外键约束检查或重复键检查时使用间隙锁。

innodb_locks_unsafe_for_binlog的效果:

(1)对UPDATE或DELETE语句来说,InnoDB仅锁定需要更新或删除的行,对不能够被WHERE条件匹配的行施加的锁会在条件检查后予以释放。这可以有效地降低死锁出现的概率;

(2)执行UPDATE语句时,如果某行已经被其它语句锁定,InnoDB会启动一个“半一致性(semi-consistent)”读操作从MySQL最近一次提交版本中获得此行,并以之判定其是否能够并当前UPDATE的WHERE条件所匹配。如果能够匹配,MySQL会再次对其进行锁定,而如果仍有其它锁存在,则需要先等待它们退出。

(3)innodb_locks_unsafe_for_binlog可能会造成幻读

示例一:innodb_locks_unsafe_for_binlog=off的情况下:

mysql> show create table t4\G

*************************** 1. row ***************************

Table: t4

Create Table: CREATE TABLE `t4` (

`id` int(11) NOT NULL,

`id1` int(11) DEFAULT NULL,

`id2` int(11) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

1 row in set (0.00 sec)

mysql> show create table t5\G

*************************** 1. row ***************************

Table: t5

Create Table: CREATE TABLE `t5` (

`id` int(11) NOT NULL,

`id1` int(11) DEFAULT NULL,

`id2` int(11) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

1 row in set (0.00 sec)

mysql> show variables like 'innodb_locks_unsafe_for_binlog';

+--------------------------------+-------+

| Variable_name | Value |

+--------------------------------+-------+

| innodb_locks_unsafe_for_binlog | OFF |

+--------------------------------+-------+

1 row in set (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t4;

+----+------+------+

| id | id1 | id2 |

+----+------+------+

| 1 | 1 | 1 |

| 2 | 2 | 2 |

| 3 | 3 | 3 |

| 4 | 4 | 4 |

| 5 | 5 | 5 |

+----+------+------+

5 rows in set (0.00 sec)

mysql> select * from t5;

Empty set (0.00 sec)

mysql> insert into t5 select * from t4 where id2=3;

Query OK, 1 row affected (0.34 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> update t4 set id1=33 where id2=3; //被hang住

mysql> commit;

Query OK, 0 rows affected (0.01 sec)

Query OK, 1 row affected (9.15 sec) //事物一提交后,update操作执行成功

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from t5;

+----+------+------+

| id | id1 | id2 |

+----+------+------+

| 3 | 3 | 3 |

+----+------+------+

1 row in set (0.00 sec)

mysql> select * from t4 where id2=3;

+----+------+------+

| id | id1 | id2 |

+----+------+------+

| 3 | 3 | 3 |

+----+------+------+

1 row in set (0.00 sec)

示例二:innodb_locks_unsafe_for_binlog=on的情况下

mysql> show variables like 'innodb_locks_unsafe_for_binlog';

+--------------------------------+-------+

| Variable_name | Value |

+--------------------------------+-------+

| innodb_locks_unsafe_for_binlog | ON |

+--------------------------------+-------+

1 row in set (0.35 sec)

mysql> select * from t4;

+----+------+------+

| id | id1 | id2 |

+----+------+------+

| 1 | 1 | 1 |

| 2 | 2 | 2 |

| 3 | 3 | 3 |

| 4 | 4 | 4 |

| 5 | 5 | 5 |

+----+------+------+

5 rows in set (0.00 sec)

mysql> select * from t5;

Empty set (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t5 select * from t4 where id2=3;

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> select * from t5;

+----+------+------+

| id | id1 | id2 |

+----+------+------+

| 3 | 3 | 3 |

+----+------+------+

1 row in set (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> update t4 set id2=333 where id2=3; //事物一未提交的情况下,直接更新成功,不会有阻塞

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from t4 where id=3;

+----+------+------+

| id | id1 | id2 |

+----+------+------+

| 3 | 3 | 333 |

+----+------+------+

1 row in set (0.00 sec)

mysql> select * from t5;

Empty set (0.00 sec)

mysql> commit; //事物二先提交

Query OK, 0 rows affected (0.00 sec)

mysql> commit; //事物一后提交

Query OK, 0 rows affected (0.01 sec)

mysql> select * from t5;

+----+------+------+

| id | id1 | id2 |

+----+------+------+

| 3 | 3 | 3 |

+----+------+------+

1 row in set (0.00 sec)

mysql> select * from t4 where id=3;

+----+------+------+

| id | id1 | id2 |

+----+------+------+

| 3 | 3 | 333 |

+----+------+------+

1 row in set (0.00 sec)

查看binlog日志:

BEGIN

/*!*/;

# at 565

#180926 16:27:06 server id 1013306 end_log_pos 609 Table_map: `test1`.`t4` mapped to number 125

# at 609

#180926 16:27:06 server id 1013306 end_log_pos 667 Update_rows: table id 125 flags: STMT_END_F

BINLOG '

muurWxM6dg8ALAAAAGECAAAAAH0AAAAAAAEABXRlc3QxAAJ0NAADAwMDAAY=

muurWx86dg8AOgAAAJsCAAAAAH0AAAAAAAEAAgAD///4AwAAAAMAAAADAAAA+AMAAAADAAAATQEA

AA==

'/*!*/;

### UPDATE `test1`.`t4` //事物二先提交,所以binlog日志中先记录对t4的更新操作

### WHERE

### @1=3 /* INT meta=0 nullable=0 is_null=0 */

### @2=3 /* INT meta=0 nullable=1 is_null=0 */

### @3=3 /* INT meta=0 nullable=1 is_null=0 */

### SET

### @1=3 /* INT meta=0 nullable=0 is_null=0 */

### @2=3 /* INT meta=0 nullable=1 is_null=0 */

### @3=333 /* INT meta=0 nullable=1 is_null=0 */

# at 667

#180926 16:28:38 server id 1013306 end_log_pos 694 Xid = 82

COMMIT/*!*/;

# at 694

#180926 16:28:52 server id 1013306 end_log_pos 755 GTID last_committed=1 sequence_number=3 rbr_only=yes

/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;

SET @@SESSION.GTID_NEXT= 'f2754eef-6a6e-11e8-8b99-000c2971d3ea:1451'/*!*/;

# at 755

#180926 16:25:57 server id 1013306 end_log_pos 824 Query thread_id=2 exec_time=0 error_code=0

SET TIMESTAMP=1537993557/*!*/;

BEGIN

/*!*/;

# at 824

#180926 16:25:57 server id 1013306 end_log_pos 868 Table_map: `test1`.`t5` mapped to number 126

# at 868

#180926 16:25:57 server id 1013306 end_log_pos 912 Write_rows: table id 126 flags: STMT_END_F

BINLOG '

VeurWxM6dg8ALAAAAGQDAAAAAH4AAAAAAAEABXRlc3QxAAJ0NQADAwMDAAY=

VeurWx46dg8ALAAAAJADAAAAAH4AAAAAAAEAAgAD//gDAAAAAwAAAAMAAAA=

'/*!*/;

### INSERT INTO `test1`.`t5` //事物一后提交所以对于insert ... select 操作在binlog中后记录,但是set的记录仍然是事物二为修改之前的值

### SET

### @1=3 /* INT meta=0 nullable=0 is_null=0 */

### @2=3 /* INT meta=0 nullable=1 is_null=0 */

### @3=3 /* INT meta=0 nullable=1 is_null=0 */

# at 912

#180926 16:28:52 server id 1013306 end_log_pos 939 Xid = 78

COMMIT/*!*/;

SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;

DELIMITER ;

因此,当innodb_locks_unsafe_for_binlog=on的情况下,会让你容易造成数据的不一致。

七、自增长锁

自增长锁是一种表级锁,专门针对auto_increment类型的列。

自增长列锁各模式分析:

innodb_autoinc_lock_mode:自增长长锁模式

0:

不管是insert into values (simple insert)还是insert into select (bulk insert),都是:持有锁、读取/修改、执行SQL、释放,不需要等到事务提交就释放锁,但是需要SQL执行完成,并且不能保证连续。

持有latch ---> 读取和修改auto锁 ---> 执行insert ---> 释放

注意:不需要等待insert所在的事务是否提交

缺点:可能出现数字不连续

持有时间相对过长:SQL执行完毕,不需要事务提交

1:

默认值,对于回滚是不能保证自增长列连续的。

对于simple insert (insert into values):持有锁、读取、释放、执行SQL,最快,不需要执行完SQL就释放,不需要等待insert执行完毕就可以释放锁。

对于bulk insert (insert into select):持有锁、读取、执行SQL、释放,需要执行完SQL才释放。(对于批量insert来说等同于0)

优点:

对于simple insert 来说,性能比0好些,对于批量来说,性能等同于0

缺点:

数字不连续

对于批量来说持有锁的时间相对过长

2:

经常改为2,主要是为了唯一,不是为了连续,在批量insert时或者批量insert并发的时候用

优点:速度最快

缺点:只能保证唯一,不能保证递增和连续。持有、读取和修改、释放、执行SQL

建议修改成2,对于批量的insert可以提升性能

示例:

1、自增长锁

t2(id automent_ment,id1 int)

mysql> show variables like 'innodb_autoinc_lock_mode';

+--------------------------+-------+

| Variable_name | Value |

+--------------------------+-------+

| innodb_autoinc_lock_mode | 1 |

+--------------------------+-------+

1 row in set (0.04 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t2(id1) values(11);

Query OK, 1 row affected (0.00 sec)

mysql> select * from t2;

+----+------+

| id | id1 |

+----+------+

| 1 | 11 |

+----+------+

1 row in set (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t2(id1) values(22);

Query OK, 1 row affected (0.03 sec)

mysql> insert into t2(id1) values(33);

Query OK, 1 row affected (0.00 sec)

mysql> select * from t2;

+----+------+

| id | id1 |

+----+------+

| 1 | 11 |

| 3 | 33 |

+----+------+

2 rows in set (0.00 sec)

mysql> select * from t2;

+----+------+

| id | id1 |

+----+------+

| 2 | 22 |

+----+------+

1 row in set (0.00 sec)

由于innodb_autoinc_lock_mode=1,所以事物一并不会阻塞事物二的simple insert,保证了id字段的唯一性

mysql 锁_浅谈MySQL的七种锁相关推荐

  1. 支付宝的数据库是MySQL变种_浅谈MySql的储存引擎(表类型)

    浅谈mysql的存储引擎(表类型) 什么是MySql数据库 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合. 我们通常说的MySql数据库, ...

  2. python中gil锁和线程锁_浅谈Python中的全局锁(GIL)问题

    CPU-bound(计算密集型) 和I/O bound(I/O密集型) 计算密集型任务(CPU-bound) 的特点是要进行大量的计算,占据着主要的任务,消耗CPU资源,一直处于满负荷状态.比如复杂的 ...

  3. mysql 安全问题_浅谈MySQL数据库的Web安全问题

    数据安全是现在互联网安全非常重要一个环节.而且一旦数据出现问题是不可逆的,甚至是灾难性的. 有一些防护措施应该在前面几个博文说过了,就不再赘述.比如通过防火墙控制,通过系统的用户控制,通过Web应用的 ...

  4. mysql重传_浅谈 MySQL 中的事务和 ACID

    所谓事务(Transaction),就是通过确保成批的操作要么完全执行,要么完全不执行,来维护数据库的完整性.举一个烂大街的例子:A 向 B 转账 1000 元,对应的 SQL 语句为:(没有显式定义 ...

  5. 谈谈mysql优化_浅谈MySQL SQL优化

    本文首发于个人微信公众号<andyqian>,期待你的关注 前言 有好几天没有写文章了,实在不好意思.之前就有朋友希望我写写MySQL优化的文章.我迟迟没有动笔,主要是因为,SQL优化这个 ...

  6. mysql 用户通配符_浅谈mysql通配符进行模糊查询的实现方法

    在mysql数据库中,当我们需要模糊查询的时候 ,我们会使用到通配符. 首先我们来了解一下2个概念,一个是操作符,一个是通配符. 操作符 like就是SQL语句中的操作符,它的作用是指示在SQL语句后 ...

  7. mysql revoke 授权_浅谈MySQL中授权(grant)和撤销授权(revoke)用法详解

    MySQL 赋予用户权限命令的简单格式可概括为: grant 权限 on 数据库对象 to 用户 一.grant 普通数据用户,查询.插入.更新.删除 数据库中所有表数据的权利 grant selec ...

  8. mysql declare与set的区别_浅谈MySQL存储过程中declare和set定义变量的区别

    在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅 ...

  9. mysql维护计划任务_浅谈MySQL event 计划任务

    一.查看event是否开启 show variables like '%sche%'; set global event_scheduler =1; 二. -- 设置时区并设置计划事件调度器开启,也可 ...

  10. mysql 计划任务消耗_浅谈MySQL event 计划任务

    一.查看event是否开启 show variables like '%sche%'; set global event_scheduler =1; 二. -- 设置时区并设置计划事件调度器开启,也可 ...

最新文章

  1. 不止JDK7的HashMap,JDK8的ConcurrentHashMap也会造成CPU 100%
  2. Javascript玩转继承(一)
  3. 基于ThinkPHP的在线编辑器调用
  4. 如何在aspx.cs 里面获取html 控件值
  5. 欠薪解决新途径:劳动者可向法院申请支付令。(拖欠工资就是违法)
  6. AVIO内存输入模式
  7. MySQL数据库迁移到PostgreSQL
  8. 接口中默认方法和静态方法_接口中的默认方法和静态方法
  9. 曲苑杂坛--修改数据库名和文件组名
  10. 你知道别人怎么看你恢复它?
  11. Web安全通讯之JWT的Java实现
  12. 推荐免费的Windows Mobile截屏软件
  13. 【python】-- 类的继承(新式类/经典类)、多态
  14. 计算机数据结构考研知识点汇总,数据结构考研知识点总结.pdf
  15. 牌匾设计软件测试自学,回弹检测测点
  16. IDEA启动报错:Error launching IDEA if you already have a 64-bit JDK installed,define a JAVA_HOME
  17. 爬虫入门实践:天气信息
  18. 11.1 项目风险管理
  19. 协众信息技术平面海报设计,你知道多少
  20. 一文读懂 Kafka 事务机制

热门文章

  1. centos7.4 update git
  2. 一个简易的C++性能分析工具
  3. sql server 2012 数据库还原方法
  4. IMP 导入数据报错 OCI-21500 OCI-22275
  5. Opencv之获取边缘和画轮廓
  6. 智能优化算法应用:基于灰狼算法的Otsu图像多阈值分割-附代码
  7. leetcode刷题日记-846. 一手顺子
  8. 【LeetCode】【字符串】题号:*657. 机器人能否返回原点
  9. Windows下配置QGIS和Python
  10. 前端实践(4)——表单验证(密码重复输入检查)