mysql isreg_`Innodb` MySQL中如何优雅的删除大表跑路
最近很想写写MySQL相关的内容,就从这个话题出发吧
有人说删MySQL表谁不会
不就是
drop table TABLENAME
如果在生产环境中,你对一张TB级别的大表,敲下这行命令
那么你的主管,大主管,隔壁的大主管 就会气势汹汹的冲向你
其原因是因为当开始Drop表的时候,因为Innodb支持事务,为保持一致性,会维护一个全局锁
这就导致,这个时候所有关于MySQL的操作全部堵在队列中
如果在白天,那QPS曲线跌零可是很好看的
当然有些不辞辛苦的DBA会选择,大晚上爬起来删表
先说结论: 先用ln建立硬链接,再drop表,最后用truncate删除索引文件
Innodb - MyISAM
目前一般MySQL引擎使用的是Innodb
其最大的特点就是支持事务,虽然Select性能比MyISAM弱一点
事务
那么什么是事务?
事务就是一件事,一堆SQL组
这些SQL要么一起完成,要么一个都不做, 它是一个不可分割的工作单位
事务是并发控制的基本单位,保证了数据的完整
事务满足著名的ACID条件
原子性: 在学习事务时,经常有人会告诉你,事务就是一系列的操作,要么全部都执行,要都不执行,这其实就是对事务原子性的刻画;虽然事务具有原子性,但是原子性并不是只与事务有关系,它的身影在很多地方都会出现
如果操作并不具有原子性,并且可以再分为多个操作,当这些操作出现错误或抛出异常时,整个操作就可能不会继续执行下去,而已经进行的操作造成的副作用就可能造成数据更新的丢失或者错误
其难点在于并行事务的原子性处理
MySQL 使用回滚日志undo log实现事务的原子性
一致性: 在事务开始之前和事务结束以后,数据库的完整性没有被破坏
其实除了ACID的一致性,CAP原则中也有一个一致性
CAP中的一致性指的是分布式系统中的各个节点中对于同一数据的拷贝有着相同的值
ACID中一致性指的是数据库的规则,如果 schema 中规定了一个值必须是唯一的,那么一致的系统必须确保在所有的操作中,该值都是唯一的
隔离性: 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致
RAED UNCOMMITED: 使用查询语句不会加锁,可能会读到未提交的行Dirty Read
READ COMMITED: 只对记录加记录锁,而不会在记录之间加间隙锁,所以允许新的记录插入到被锁定记录的附近,所以再多次使用查询语句时,可能得到不同的结果Non-Repeatable Read
REPEATABLE READ: 多次读取同一范围的数据会返回第一次查询的快照,不会返回不同的数据行,但是可能发生幻读Phantom Read
SERIALIZABLE: InnoDB 隐式地将全部的查询语句加上共享锁,解决了幻读的问题
Mysql的隔离性通过共享锁Shared、互斥锁Exclusive、时间戳、version等手段实现
持久性: 既然是数据库,那么一定对数据的持久存储有着非常强烈的需求,如果数据被写入到数据库中,那么数据一定能够被安全存储在磁盘上;而事务的持久性就体现在,一旦事务被提交,那么数据一定会被写入到数据库中并持久存储起来
MySQL 使用重做日志redo log实现事务的持久性
其他区别
储存结构
MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件), InnoDB表的大小只受限于操作系统文件的大小,一般为2GB
存储空间
MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表、动态表、压缩表
InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引
可移植性、备份及恢复
MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作
InnoDB:免费的方案可以是拷贝数据文件、备份binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了
AUTO_INCREMENT
MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增
InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列
表锁差异
MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据
InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的
全文索引
MyISAM:支持 FULLTEXT类型的全文索引
InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好
表主键
MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址
InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值
表的具体行数
MyISAM:保存有表的总行数,如果select count(*) from table;会直接取出出该值
InnoDB:没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样
CURD操作
MyISAM:如果执行大量的SELECT,MyISAM是更好的选择
InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令
外键
MyISAM:不支持
InnoDB:支持
开启独立表空间
MySQL5.6.7之后会默认开启独立表空间
在my.cnf中,有这么一条配置
innodb_file_per_table = 1
查看表空间状态,用下面的命令
mysql> show variables like '%per_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
如果innodb_file_per_table的value值为OFF,代表采用的是共享表空间。
如果innodb_file_per_table的value值为ON,代表采用的是独立表空间
共享表 - 独立表
共享表空间:某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目录下
默认的文件名为:ibdata1(此文件,可以扩展成多个)。注意,在这种方式下,运维超级不方便。你看,所有数据都在一个文件里,要对单表维护,十分不方便。另外,你在做delete操作的时候,文件内会留下很多间隙,ibdata1文件不会自动收缩。换句话说,使用共享表空间来存储数据,会遭遇drop table之后,空间无法释放的问题。
独立表空间:每一个表都以独立方式来部署,每个表都有一个.frm表描述文件,还有一个.ibd文件。
.frm文件:保存了每个表的元数据,包括表结构的定义等,该文件与数据库引擎无关。
.ibd文件:保存了每个表的数据和索引的文件。
注意,在这种方式下,每个表都有自已独立的表空间,这样运维起来方便,可以实现单表在不同数据库之间的移动。另外,在执行drop table操作的时候,是可以自动回收表空间。在执行delete操作后,可以通过执行alter table TableName engine=innodb语句来整理碎片,回收部分表空间
硬链接
假设,datadir = /data/mysql/, 另外,有一个database,名为bigtest
在数据库bigtest中,有一个表,名为TABLENAME,执行下列命令
mysql> system ls -l /data/mysql/bigtest/
-rw-r----- 1 mysql mysql 9023 8 18 11:32 TABLENAME.frm
-rw-r----- 1 mysql mysql 2356792000512 8 18 11:32 TABLENAME.ibd
现在TABLENAME.ibd文件太大,导致删表的时候过慢
那么如何解决这个问题呢,就需要使用硬链接对同一文件再建立一次索引
这个时候drop掉TABLENAME.ibd文件,那就是秒级
因为FS查询该文件还有一个索引,就不会真正的删除这张表,而只是删除这个索引
mysql> system ln /data/mysql/bigtest/TABLENAME.ibd /data/mysql/bigtest/TABLENAME.ibd.tmp
-rw-r----- 1 mysql mysql 9023 8 18 11:32 TABLENAME.frm
-rw-r----- 2 mysql mysql 2356792000512 8 18 11:32 TABLENAME.ibd
-rw-r----- 2 mysql mysql 2356792000512 8 18 11:32 TABLENAME.ibd.tmp
此时drop表,就会瞬间结束
mysql> drop table erp;
Query OK, 0 rows affected (1.03 sec)
truncate
这个时候已经把表删了 MySQL里面已经没有这张表了 但磁盘并没有释放
磁盘里还有那个TABLENAME.ibd.tmp大文件,于是问题转换为如何删除一个大文件而不引起大IO
同样这个时候不能用rm命令,用了的话磁盘IO开销飙高, CPU打满,ssh都连不上了,那么恭喜你又有:tea:喝了
那用什么呢
答案是truncate(其实还有其他一些方法, 但对IO影响都比较大)
其实有两个truncate, 一个是Linux下FS对文件操作的命令,一个是MySQL中对表操作的命令
FS的truncate
truncate 和其字面意思一致,截断
把文件截断成指定大小(注意: 可以是放大也可以是缩小)
附上truncate的Linux源码,其基本思路就是三次释放间接块,截取inode
直接块,就是i_zone中相应保存的就直接是inode所使用的磁盘块
一级间接块,顾名思义,i_zone指明的块中存放的不是普通数据,而是块号
因此对一级间接块的释放操作就是读取一级间接块,遍历其中每一个块调用free_block进行释放
二级间接块就是i_zone中存储的是一级间接块的块号
对于二级间接块读取一级间接块后就可以转换为对一级间接块的释放操作
同理,三级间接块i_zone存储的就是二级间接块的块号,所以释放三级间接块就需要三次递归
truncate操作则是对inode的所有块进行释放,最后设置其大小为0
/*
* linux/fs/truncate.c
*
* (C) 1991 Linus Torvalds
*/
#include // 调度程序头文件,定义了任务结构task_struct、初始任务0 的数据,
// 还有一些有关描述符参数设置和获取的嵌入式汇编函数宏语句。
#include // 文件状态头文件。含有文件或文件系统状态结构stat{}和常量。
// 释放一次间接块。
static void free_ind(int dev, int block) {
struct buffer_head *bh;
unsigned short *p;
int i;
if (!block) return; // 如果逻辑块号为0,则返回。
// 读取一次间接块,并释放其上表明使用的所有逻辑块,然后释放该一次间接块的缓冲区。
if (bh = bread(dev, block)) {
p = (unsigned short *)bh->b_data; // 指向数据缓冲区。
for (i = 0; i < 512; i++, p++) // 每个逻辑块上可有512 个块号。
if (*p) free_block(dev, *p); // 释放指定的逻辑块。
brelse(bh); // 释放缓冲区。
}
free_block(dev, block); // 释放设备上的一次间接块。
}
// 释放二次间接块。
static void free_dind(int dev, int block) {
struct buffer_head *bh;
unsigned short *p;
int i;
if (!block) return; // 如果逻辑块号为0,则返回。
// 读取二次间接块的一级块,并释放其上表明使用的所有逻辑块,然后释放该一级块的缓冲区。
if (bh = bread(dev, block)) {
p = (unsigned short *)bh->b_data; // 指向数据缓冲区。
for (i = 0; i < 512; i++, p++) // 每个逻辑块上可连接512 个二级块。
if (*p) free_ind(dev, *p); // 释放所有一次间接块。
brelse(bh); // 释放缓冲区。
}
free_block(dev, block); // 最后释放设备上的二次间接块。
}
// 将节点对应的文件长度截为0,并释放占用的设备空间。
void truncate(struct m_inode *inode) {
int i;
// 如果不是常规文件或者是目录文件,则返回。
if (!(S_ISREG (inode->i_mode) || S_ISDIR (inode->i_mode)))
return;
// 释放i 节点的7 个直接逻辑块,并将这7 个逻辑块项全置零。
for (i = 0; i < 7; i++)
if (inode->i_zone[i]){ // 如果块号不为0,则释放之。
free_block (inode->i_dev, inode->i_zone[i]);
inode->i_zone[i] = 0;
}
free_ind (inode->i_dev, inode->i_zone[7]); // 释放一次间接块。
free_dind (inode->i_dev, inode->i_zone[8]); // 释放二次间接块。
inode->i_zone[7] = inode->i_zone[8] = 0; // 逻辑块项7、8 置零。
inode->i_size = 0; // 文件大小置零。
inode->i_dirt = 1; // 置节点已修改标志。
inode->i_mtime = inode->i_ctime = CURRENT_TIME; // 重置文件和节点修改时间为当前时间。
}
SQL的truncate
一般说Sql的truncate会把它和drop,delete放在一起对比
我们知道MySQL有一系列的日志用于保护数据
尤其是对于写操作,除了传统的transaction log,另外还有binlog
这一些log日志都是在操作的同时进行书写的
delete操作时,会把每条数据标记为已删除,不可避免的导致了操作十分耗时,且实际上空间并没有被释放 DML
truncate操作时,把所有数据删除,仅把表结构记录到transition log中,很明显这种操作较难恢复,但耗时较少 DDL
drop表的时候,就跟直接,把表数据和表结构都删除了 DDL
drop和truncate想要恢复也是可以的但不是通过rollback,而是通过解析binlog文件
其他方法
重定向
把空字符重定向到文件中,但IO高,io会跌零
$ > /data/mysql/bigtest/TABLENAME.ibd.tmp
:/true
把true值重定向到文件中
$ : > /data/mysql/bigtest/TABLENAME.ibd.tmp
/dev/null/dd/cp
cat /dev/null > access.log
cp /dev/null access.log
dd if=/dev/null of=access.log
echo
echo "" > access.log
echo > access.log
echo -n "" > access.log
HDFS truncate
Truncate文件截断在HDFS上的表现其实是block的截断。传入目标文件,与目标保留的长度(此长度应小于文件原大小)
允许用户移除意外写入的数据
当写事务发生失败的时候,可以进行回滚,回到之前写入成功的事务状态
有能力移除一次失败的写操作而写入的不完整的数据
提升HDFS对于其它文件系统的支持度
定位到新的截取长度所对应的块,然后把后面多余的块从此文件中进行移除;
找到新长度所对应的block块之后,计算此块内部需要移除的偏移量,然后进行删除;
参考
相关文章:

常用正则表达式集锦
链接地址:http://blog.csdn.net/tjcyjd/article/details/48416405 验证数字:^[0-9]*$验证n位的数字:^\d{n}$验证至少n位数字:^\d{n,}$验证m-n位的数字:^\d{m,n}$验证零和非零开头的数字:^(0|[1-9][0-9]*)$验…

C(第一个C程序) 和 C++ (第一个C++程序)对比碰撞
个人博客首页(点击查看详情) -- https://blog.51cto.com/11495268 1、简介 C 是对 C 的继承、扩展,但从语言角度来说,这是 两种变成语言,就一定存在不同,本文 就借助于 C、C 的 最精简标准程序 进行对比…

java的byte与C#的异同引起的字符处理问题。
java的byte是有符号类型(java就没有无符号类型的数据),值域:-0128~127 c#的byte是无符号类型数值,值域:0~255 这在依赖字符编码处理程序中,两者源代码就不能通用了。 知道原因结局办法就容易多了。 1.使用&与运算 …

exec不同文件l怎么汇总_ABAQUS常见问题汇总 - 2.0版.doc
您所在位置:网站首页 > 海量文档 > 计算机 > C/C资料ABAQUS常见问题汇总 - 2.0版.doc154页本文档一共被下载:次,您可全文免费在线阅读后下载本文档。下载提示1.本站不保证该用户上传的文档完整性,…

1月12号 UIView
UIView 1.为什么要UIView .可以用UIView作为容器,存放子视图 .管理事件UIEvent 2.ios坐标系 以左上角为坐标原点,向右边是x的正方向,向下是y的正向方 bounds: 相对于视图本身而言(0,0,w, h) fra…

小虎计算器-技术支持
2019独角兽企业重金招聘Python工程师标准>>> 最简单的计算器,包含历史记录 转载于:https://my.oschina.net/u/1405818/blog/3050764

jquery即时搜索查询插件jquery.search.js
jquery.search.js搜索插件是一款基于jquery的插件,任何一个input输入款均可即时转为查询框,可分为前台数据直接显示和后台传输数据显示两种方案! 文档说明:http://www.sameus.com 代码下载地址: http://code.google.com/p/17sameus/downloads/list 使用方式 jquery.search.js插…

node mysql 批量写入_请问如何使用node.js在MySQL中进行批量插入
catspeake我四处寻找关于批量插入对象的答案。Ragnar123的回答使我得出了这样的结论:function bulkInsert(connection, table, objectArray, callback) {let keys Object.keys(objectArray[0]);let values objectArray.map( obj > keys.map( key > obj[key]…

win10 UWP 应用设置
win10 UWP 应用设置 简单的把设置需要的,放到微软自带的LocalSettings LocalSettings.Values可以存放几乎所有数据 如果需要存放复合数据,一个设置项是由多个值组成,可以使用ApplicationDataCompositeValue将多个合并。 存放一个string strin…

通过loganalyzer展示数据库中的日志
目的:通过loganalyzer展示数据库中的日志 准备环境: CentOS7_1:用来生成日志 CentOS7_2:用来存放日志的数据库 CentOS7_3:LAP服务器 第一步:在CentOS7_2安装mysql数据库 此处使用二进制安装mariadb…

libmemcached 1.0.11 发布
libmemcached 1.0.11 删除了 memcached 的定制版本,更新了硬化(hardening)规则,修复了 socket 连接返回错误的问题。 libmemcached是C客户端到memcached服 务器的接口库。具有低内存占用率、线程安全、并提供对memcached功能的全面支持。它还采用多种命令…

python描述器做权限控制_Python装饰器14-描述器
描述器这是Python一个重要的概念,英文名:Descriptordescriptor是对象的一个属性,只不过它存在于类的dict中并且有特殊方法get(可能还有set和__delete)而具有一点特别的功能,为了方便指代这样的属性,我们给它起了个名字叫descripto…

数据结构(1)有序表查找
有序表查找 /* 主函数 */public class OrderTableSearch {public static void main(String[] args) {int [] a {0,1,16,24,35,47,59,62,73,88,99}; System.out.println(FibonacciSearch(a, 10, 88));System.out.println(InsertKeySearch(a, 10, 88));System.out.println(Bina…

Java实现MD5(32/16位大小写)加密
MD5简单介绍 大家都知道,地球上任何人都有自己独一无二的指纹,这常常成为公安机关鉴别罪犯身份最值得信赖的方法;与之类似,MD5就可以为任何文件(不管其大小、格式、数量)产生一个同样独一无二的“数字指纹”…

OD使用教程6 - 调试篇06|解密系列
OD使用教程6 - 调试篇06 让编程改变世界 Change the world by program 这一讲开始,小甲鱼带大家接触真正程序的逆向。其实也没啥大不了的,也就是对之前所学的知识进行巩固和加强。 不过,在每一节课中,小甲鱼都会教给大家不同的新…

宝塔面板 mysql装不上_宝塔面板强制安装mysql8.0
释放双眼,带上耳机,听听看~!mysql终于更新到8.0,mysql8.0对比以往的版本有了很大的提升,但是要求的服务器配置也就变得越来越高。对于低配置服务器,在宝塔面板进行安装时,总会出现“至少需要2个…

android studio 怎么运行java
方法/步骤 1、新建一个project,或者如果已经有project的话,那就直接新建一个module.注意选择Java library,然后下一步 2、输入module的一些信息。点击finish 3、在左侧找到build.gradle,双击打开,参照图中修改一下配置…

运行PHP出现No input file specified错误解决办法
配置了一台新服务器,使用的是IIS Fastcgi PHP 5.3.X,访问php页面的时候就会报错“No input file specified” 在php.ini文件里面修改: 1、增加一行(这个最重要) fastcgi.impersonate 1 2、修改两项(解开…

Microsoft Security Essentials 4.1.522.0 RTM
简单说一下新版本的新功能,其中最强的是云端修复系统受损或病毒感染文件功能、重新编写的网络检查系统防御病毒入侵、新增自我保护,后台监控主进程无法用任务管理器结束。 Microsoft Security Essentials 是 Microsoft 提供的免费杀毒下载软件࿰…

wincc vbs mysql_Wincc VBS操作txt及SQL2005
系统:Win7 32Bits 旗舰版wincc: 7.0 sp3英文版Dim strConnectionStringDim objConnectionDim objCommandDim strSQLDim RsDim sdayDim smonthDim edayDim emonthDim str1Dim str2Dim tempDim sqlwhereDim msgDim CDG, WSH, FilePathDim fso, fo, slDim read_tempDim OrderFileN…

[Python]网络打解包
Python与C、C交互的时候,如果进行网络消息的收发,需要讲数据打包解包为字节流。 这时候就会用到Struct模块中的pack、unpack函数 打包: PKG # ! means network byte#PkgHeadPKG pack(!i, 0x54434d) #intPKG pack(!H, 4) #us…

TiKV 成功晋级 CNCF 孵化项目
今天,CNCF(Cloud Native Computing Foundation,云原生计算基金会)技术监督委员会(TOC)宣布已经投票决议通过,正式将 TiKV 从沙箱项目晋级至孵化项目。 TiKV 是一个开源的分布式事务 Key-Value 数…

平均符号熵的计算公式_交叉熵(Cross Entropy)从原理到代码解读
交叉熵(Cross Entropy)是Shannon(香浓)信息论中的一个概念,在深度学习领域中解决分类问题时常用它作为损失函数。原理部分:要想搞懂交叉熵需要先清楚一些概念,顺序如下:1.自信息量—>2.信息熵(熵)—>3.相对熵(KL散度)—>…

在 Ubuntu 配置 PPTP Server
本文在 Ubuntu 12.4 或 14 亲测有效。 建立 PPTP 服务器 首先安装 pptp 服务器。 # apt-get install pptpd 然后配置 pptpd。 # sudo vi /etc/pptpd.conf 在 pptpd.conf 文件末尾添加服务器 IP 和客户端 IP。 localip 192.168.3.1 remoteip 192.168.3.100-200 以上配置意味着服…

IAP超级详解,偷懒了,不用自己去翻译了
转载自:http://gaohaijun.blog.163.com/blog/static/176698271201143194018328/ 一、In App Purchase概览 Store Kit代表App和App Store之间进行通信。程序将从App Store接收那些你想要提供的产品的信息,并将它们显示出来供用户购买。 当用户需要购买某件…

linux负载均衡(什么是负载均衡)
linux负载均衡(什么是负载均衡) 一、总结 一句话总结: 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。 关键点一:…

win8数据源设置mysql_Win8系统ODBC数据源有何重要功能?
对计算机发展比较有研究的朋友一定会知道ODBC,它是一个比较古老的东西,发展到现在Win8系统上版本已经是3.8了。微软虽然没有对ODBC做很大的更新,但是正因为ODBC是一个比较成熟和古老的规范,因此它的作用才显得不那么突出ÿ…
【HTML/XML 11】XML和HTML的混合使用
导读:在前面介绍了很多关于XML和HTML的东西,他们其实各有各的好处,在很多时候都需要结合起来使用。现在已经有XML和HTML结合的产物:XHTML(可扩展超文本标记语言)。在本篇博客中,则主要介绍通过引…

web架构之mysql服务器
SQL概述结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名。从上可以看出我们数据库…
ORM查询语言(OQL)简介--概念篇
相关文章内容索引: ORM查询语言(OQL)简介--概念篇ORM查询语言(OQL)简介--实例篇ORM查询语言(OQL)简介--高级篇:脱胎换骨ORM查询语言(OQL)简介--高级篇&#x…