mysql load 相关实验步骤是怎样的
发布时间:2022-01-13 14:16:22 所属栏目:MySql教程 来源:互联网
导读:本篇文章为大家展示了mysql load 相关实验过程是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 一:load 的过程相当于是:先start transaction,然后再insert数据,最后commit 我猜测mysql 区别于oracl
本篇文章为大家展示了mysql load 相关实验过程是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 一:load 的过程相当于是:先start transaction,然后再insert数据,最后commit 我猜测mysql 区别于oracle sqlldr,没有后者的rows的参数来控制每次提交的数据行 但是我感觉 mysql 是自己通过估算出一个值,来批量读取 ,我觉得他不是 一条一条的 insert的 二:load 如果数据存在(主键或者唯一键),默认是跳过的,可以选择replace存在就替换! 三:load 没有类似于oracle的 sqlldr的rows参数来控制每次提交的行数,只能先通过linux命令来 切分(split)成小文件来实现并行; 实验一:load会不会锁表 session1 [root@beijing-fuli-hadoop-04 ~]# cat /data/t.txt 100, liu ,18 102, liu ,18 101, liu, 18 root@localhost : (none) 11:50:05>start transaction; Query OK, 0 rows affected (0.00 sec) root@localhost : (none) 11:51:08>LOAD DATA LOCAL INFILE '/data/t.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY 'n' ; Query OK, 3 rows affected (0.03 sec) Records: 3 Deleted: 0 Skipped: 0 Warnings: 0 然后不commit! session2 如下全部等待 root@localhost : liuwenhe 11:52:36>delete from t where id=101; root@localhost : liuwenhe 11:52:36>delete from t where id=102; root@localhost : liuwenhe 11:52:36>delete from t where id=103; 如下 不等待 delete from t where id=104 delete from t where id=100 结论: load 在提交之前,会锁定所有刚load的数据!!!也间接的说明这是一个事务把三个数据 都load进去了,会不会是 mysql 默认把N行数据作为一个事务呢?采用大数据量来做验证 实验二:load是不是一个事务 1.文件/data/12.txt是26135101行数据的文件 2.然后开始load root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/12.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY 'n' ; 3.另开一个会话,查询数据,发现再load完成之前一直是空, root@localhost : liuwenhe 13:55:15>select count(*) from t; +----------+ | count(*) | +----------+ | 0 | +----------+ 1 row in set (0.66 sec) 这就进一步说明 load操作是一个事务的!!! 实验三:是否允许在同一个表上同时进行load? 只要没有冲突是可以并行的! 这里所说的冲突是指: 已经load 处理了的数据中和另一个会话要处理的数据有冲突,具体实验如下: 假如1.txt 文件 是id从1到2147483647这个范围的数据,而2.txt是id=2147483647的 一条数据,而3.txt是id从1到3的范围并且还有id=2147483646这条数据 具体如下: [root@beijing-fuli-hadoop-04 liuwenhe]# cat 2.txt 26293013,liu ,18 [root@beijing-fuli-hadoop-04 liuwenhe]# cat 3.txt 1, liu ,18 26293013,liu ,18 具体实验过程: 实验1) 会话1: 执行这个,因为数据量比较大,所以会执行一会 root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/liuwenhe/1.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY 'n' ; 会话2: [root@beijing-fuli-hadoop-04 liuwenhe]# cat 2.txt 26293013,liu ,18 然后会话1还没有结束呢,执行如下操作,发现没有等待!确实进去了, root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/liuwenhe/2.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY 'n' ; root@localhost : liuwenhe 17:33:18>select * from t where id =26293013; +----------+-------+------+ | id | name | num | +----------+-------+------+ | 26293013 | liu | 18 | +----------+-------+------+ 1 row in set (0.12 sec) 说明:load顺序执行,当执行到的id=1的数据到达innodb层,mysql就会把id=1的数据上锁gap锁, 这时候你再load=1的数据就会有锁等待,但是你没有执行到id=26293013的数据,也就没有给这条数据上锁,所以你并行执行另一个load (id=26293013)的数据就不会等待。 实验2) 会话1: 执行这个,因为数据量比较大,所以会执行一会 root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/liuwenhe/1.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY 'n' ; 会话2: 在会话1还没有结束的时候,执行如下发现等待,因为id=1的数据被会话1锁定,所以下面的操作是需要等待的,因为load 3.txt是先处理id=1的数据,但是它已经被锁定了, [root@beijing-fuli-hadoop-04 liuwenhe]# cat 3.txt 1, liu ,18 26293013,liu ,18 root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/3.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY 'n' ; 实验3)load 产生死锁: 会话1: 执行这个,因为数据量比较大,所以会执行一会; root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/liuwenhe/1.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY 'n' ; 会话2: 在会话1还没有结束的时候,执行如下发现等待,因为id=1的数据被会话1锁定,但是id=26293013的数据没有被锁定呢,所以说load 4.txt的时候,能把第一条数据(id=26293013)load进innodb引擎层并且锁定,但是1这条数据却被锁定,进而会话1和会话2产生锁等待! [root@beijing-fuli-hadoop-04 liuwenhe]# cat 4.txt 26293013,liu ,18 1, liu ,18 root@localhost : (none) 18:13:10>LOAD DATA LOCAL INFILE '/data/liuwenhe/4.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY 'n' ; ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction 注释:为什么会选择回滚会话2的事务?因为我开启了死锁检测,然后数据库选择插入更新或者删除的行数最少的事务回滚 MySQL 如何处理死锁? MySQL有两种死锁处理方式: 等待,直到超时(innodb_lock_wait_timeout=50s)。 发起死锁检测,主动回滚一条事务,让其他事务继续执行(innodb_deadlock_detect=on)。 由于性能原因,一般都是使用死锁检测来进行处理死锁。 死锁检测 死锁检测的原理是构建一个以事务为顶点、锁为边的有向图,判断有向图是否存在环,存在即有死锁。 回滚 检测到死锁之后,选择插入更新或者删除的行数最少的事务回滚,基于 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段来判断。 (编辑:聊城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐