zoukankan      html  css  js  c++  java
  • MySQL 多会话之间更新数据的小实例

    1:创建一个实验表

    mysql> use test;
    
    mysql> CREATE TABLE t
        -> (id int(11) NOT NULL DEFAULT 0,
        -> num int(11) DEFAULT NULL,
        -> PRIMARY KEY(id))
        -> ENGINE=INNODB DEFAULT CHARSET=gbk;
    Query OK, 0 rows affected (0.02 sec)
    

      

    mysql> INSERT INTO t VALUES(1,100);
    
    mysql> INSERT INTO t VALUES(2,200);
    
    Session A Session B
    mysql> BEGIN;  
    mysql> SELECT * FROM t;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |  100 |
    |  2 |  200 |
    +----+------+
    2 rows in set (0.00 sec)
    

      

     
     
    mysql> USE test
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    mysql> INSERT INTO t VALUES(3,300);
    Query OK, 1 row affected (0.01 sec)
    

      

    mysql> SELECT * FROM t;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |  100 |
    |  2 |  200 |
    +----+------+
    2 rows in set (0.00 sec)
    
     
    mysql> UPDATE t SET num=1000 WHERE id=3;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    

    上述查看并没有id=3的列,这里居然成功了!

     
    mysql> SELECT * FROM t;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |  100 |
    |  2 |  200 |
    |  3 | 1000 |
    +----+------+
    3 rows in set (0.00 sec)
    

      

     
    从Session A整个过程看来,它试图更新一个不存在的记录(id=3),结果更新成功,并且之后这个记录可以访问。
    
    为什么SessionA第二次检索仍然是2条记录呢?
    
        Innodb内部每个事务开始时,都会有一个事务id,同时事务对象中还有一个read_view变量,用于控制该事务可见的记录范围(MVCC)。
    
        对于每个访问到的记录行,会根据read_view的trx_id(事务id)与行记录的trx_id比较,判断记录是否逻辑上可见。
    
        Session B中插入的记录不可见,原因即为Session A先于session B,因此新插入的数据经过判断,不在可见范围内。对应的源码在row/row0sel.c [4040-4055].
    

      

    Session A Session B
    mysql> SELECT * FROM t;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |  100 |
    |  2 |  200 |
    |  3 | 1000 |
    +----+------+
    3 rows in set (0.00 sec)
    

      

     
     
    mysql> INSERT INTO t VALUES(4,400);
    Query OK, 1 row affected (0.01 sec)
    

      

    mysql> SELECT * FROM t;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |  100 |
    |  2 |  200 |
    |  3 | 1000 |
    +----+------+
    3 rows in set (0.00 sec)
    

      

     
    mysql> COMMIT;
    Query OK, 0 rows affected (0.00 sec)
    

      

     
    mysql> SELECT * FROM t;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |  100 |
    |  2 |  200 |
    |  3 | 1000 |
    |  4 |  400 |
    +----+------+
    4 rows in set (0.00 sec)
    

    提交之后正常可见

     
  • 相关阅读:
    【漏洞分析】dedecms有前提前台任意用户密码修改
    关于t00ls的挂机脚本
    关于pocsuite的使用
    [代码审计]青云客Cms前台有条件注入至getshell,后台xss至getshell、至弹你一脸计算器
    警惕phpstudy等开发神器使用默认配置可能带来的危险
    [代码审计]DM企业建站系统v201710 sql注入漏洞分析 | 新版v201712依旧存在sql注入
    [代码审计]XiaoCms(后台任意文件上传至getshell,任意目录删除,会话固定漏洞)
    对长短按设置不同反应 安卓
    如何数冲突域(collision domains)个数
    Computer Network Homework2’s hard question
  • 原文地址:https://www.cnblogs.com/xiaoit/p/4003290.html
Copyright © 2011-2022 走看看