从数据库碎片
MySQL 8.0.16 已经发布,它像往常一样增强了组复制 Group Replication 功能。
这篇文章介绍了 MySQL 8.0.16 为 Group Replication 带来的新功能:
Message fragmentation(信息碎片化)。
背景
Group Replication 目前使用 XCom(一种组通信引擎),特点:原子性,组员状态检测等。每个成员的组复制插件先将信息转发到本地 XCom,再由 XCom 最终以相同的顺序将信息传递给每个组成员的 Group Replication 插件。
XCom 由单线程实现。当一些成员广播信息过大时,XCom 线程必须花费更多的时间来处理那个大信息。如果成员的 XCom 线程忙于处理大信息的时间过长,它可能会去查看其他成员的 XCom 实例。例如,忙碌的成员失效。如果是这样,该组可以从该组中驱逐忙碌的成员。
MySQL 8.0.13 新增group_replication_member_expel_timeout系统变量,您可以通过它来调整将成员从组中驱逐的时间。例如,怀疑成员失败,但成员实际上忙于处理大信息,给成员足够的时间来完成处理。在这种情况下,是否为成员增加驱逐超时的设置是一种权衡。有可能等了很久,该成员实际真的失效了。
Message fragmentation(信息碎片化)
MySQL 8.0.16 的 Group Replication 插件新增用来处理大信息的功能:信息碎片化。
简而言之,您可以为成员的广播信息指定最大值。超过最大值的信息将分段为较小的块传播。
您可以使用 group_replication_communication_max_message_size系统变量指定允许的信息最大值(默认值为10 MiB)。
示例
让我们用一个例子来解释新功能。图1显示了当绿色成员向组广播信息时,新功能是如何处理的。
图1 对传出信息进行分段
1. 如果信息大小超过用户允许的最大值(group_replication_communication_max_message_size),则该成员会将信息分段为不超过最大值的块。
2. 该成员将每个块广播到该组,即将每个块单独转发到XCom。
XCom 最终将这些块提供给组成员。下面三张图展示出了中间绿色成员发送大信息时工作的新特征。
图2a 重新组合传入的信息:第一个片段
3. 成员得出结论,传入的信息实际上是一个更大信息的片段。
4. 成员缓冲传入的片段,因为他们认为片段是仍然不完整的信息的一部分。(片段包含必要的元数据以达到这个结论。)
图2b 重新组合传入的信息:第二个片段
5. 见上面的第3步。
6. 见上面的第4步。
图2c 重新组合传入的信息:最后一个片段
7. 成员得出结论,传入的信息实际上是一个更大信息的片段。
8. 成员得出结论,传入的片段是最后一个缺失的块,重新组合原始信息,然后对其进行处理,传输完毕。
结论
MySQL 8.0.16 已经发布后,组复制现在可以确保组内交换的信息大小不超过用户定义的阈值。这可以防止组内误判而驱逐成员。
Ⅱ 什么是内部碎片什么是外部碎片各种存储管理中都可能产生何种碎片
1.内部碎片:
当一个进程装入到固定大小的分区块(比如页)时,假如进程所需空间小于分区块,则分区块的剩余的空间将无法被系统使用,称为内部碎片。
2.外部碎片:
指的是还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。
3.存储管理中都可能产生的碎片:
除了内部碎片和外部碎片,在“分页存储”中,可能产生“页内碎片”,页内碎片是由于进程的最后一页经常装不满一块而形成了不可利用的碎片。
(2)从数据库碎片扩展阅读
在数据存储领域中,碎片(fragmentation)是指存储空间使用效率低下,结果导致功能、运行效率变低或二者兼而有之的现象。碎片化所造成的影响取决于具体的存储系统以及碎片化的种类。
大部分情况下,碎片化都会导致都会导致存储空间的浪费,此时“碎片”一词亦可指代闲置的空间本身。对于其他的一些系统来说(比如FAT文件系统),数据量一定的前提下,用于存储数据所占的存储空间是一定的,和碎片化的程度无关。
Ⅲ 如何检查sql数据库索引填充因子是否产生碎片以及如何处理
这是收藏的一些资料:
SQLServer提供了一个数据库命令――DBCC SHOWCONTIG――来确定一个指定的表或索引是否有碎片。
示例:
显示数据库里所有索引的碎片信息
DBCC SHOWCONTIG WITH ALL_INDEXES
显示指定表的所有索引的碎片信息
DBCC SHOWCONTIG (authors) WITH ALL_INDEXES
显示指定索引的碎片信息
DBCC SHOWCONTIG (authors,aunmind)
DBCC 执行结果:
扫描页数:如果你知道行的近似尺寸和表或索引里的行数,那么你可以估计出索引里的页数。看看扫描页数,如果明显比你估计的页数要高,说明存在内部碎片。
扫描扩展盘区数:用扫描页数除以8,四舍五入到下一个最高值。该值应该和DBCC SHOWCONTIG返回的扫描扩展盘区数一致。如果DBCC SHOWCONTIG返回的数高,说明存在外部碎片。碎片的严重程度依赖于刚才显示的值比估计值高多少。
扩展盘区开关数:该数应该等于扫描扩展盘区数减1。高了则说明有外部碎片。
每个扩展盘区上的平均页数:该数是扫描页数除以扫描扩展盘区数,一般是8。小于8说明有外部碎片。
扫描密度[最佳值:实际值]:DBCC SHOWCONTIG返回最有用的一个百分比。这是扩展盘区的最佳值和实际值的比率。该百分比应该尽可能靠近100%。低了则说明有外部碎片。
逻辑扫描碎片:无序页的百分比。该百分比应该在0%到10%之间,高了则说明有外部碎片。
扩展盘区扫描碎片:无序扩展盘区在扫描索引叶级页中所占的百分比。该百分比应该是0%,高了则说明有外部碎片。
每页上的平均可用字节数:所扫描的页上的平均可用字节数。越高说明有内部碎片,不过在你用这个数字决定是否有内部碎片之前,应该考虑fill factor(填充因子)。
平均页密度(完整):每页上的平均可用字节数的百分比的相反数。低的百分比说明有内部碎片。
解决碎片问题 :
1. 删除并重建索引
2. 使用DROP_EXISTING子句重建索引
3. 执行DBCC DBREINDEX
4. 执行DBCC INDEXDEFRAG
删除并重建索引 :
用DROP INDEX和CREATE INDEX或ALTER TABLE来删除并重建索引有些缺陷包括在删除重建期间索引会消失。在索引删除重建时,对于查询它不在可用,查询性能也许会受到明显的影响,直到重建索引为止。另一个潜在的缺陷是当都请求索引的时候会引起阻塞,直到重建索引为止。通过其他的处理也能解决阻塞,就是索引被使用的时候不删除索引。另一个主要的缺陷是在用DROP INDEX和CREATE INDEX重建聚集索引时会引起非聚集索引重建两次。删除聚集索引时非聚集索引的行指针会指向数据堆,聚集索引重建时非聚集索引的行指针又会指回聚集索引的行位置。
删除并重建索引的确有一个好处就是通过重新排序索引页,使索引页紧凑并删除不需要的索引页来完全重建索引。你也许需要考虑那些内部和外部碎片都很高的情况下才使用,以使那些索引回到它们应该在的位置。
使用DROP_EXISTING子句重建索引 :
为了避免在重建聚集索引时表上的非聚集索引重建两次,可以使用带DROP_EXISTING子句的CREATE INDEX语句。这个子句会保留聚集索引键值,以避免非聚集索引重建两次。和删除并重建索引一样,该方法也可能会引起阻塞和索引消失的问题。该方法的另一个缺陷是也强迫你去分别发现和修复表上的每一个索引。
除了和上一个方法一样的好处之外,该方法的好处是不必重建非聚集索引两次。这样可以对那些带约束的索引提供正确的索引定义以符合约束的要求。
执行DBCC DBREINDEX :
DBCC DBREINDEX类似于第二种方法,但它物理地重建索引,允许SQLServer给索引分配新页来减少内部和外部碎片。DBCC DBREINDEX也能动态的重建带约束的索引,不象第二种方法。
DBCC DBREINDEX的缺陷是会遇到或引起阻塞问题。DBCC DBREINDEX是作为一个事务来运行的,所以如果在完成之前中断了,那么你会丢失所有已经执行过的碎片。
执行DBCC INDEXDEFRAG :
DBCC INDEXDEFRAG(在SQLServer2000中可用)按照索引键的逻辑顺序,通过重新整理索引里存在的叶页来减少外部碎片,通过压缩索引页里的行然后删除那些由此产生的不需要的页来减少内部碎片。它不会遇到阻塞问题但它的结果没有其他几个方法彻底。这是因为DBCC INDEXDEFRAG跳过了锁定的页且不使用任何新页来重新排序索引。如果索引的碎片数量大的话你也许会发现DBCC INDEXDEFRAG比重建索引花费的时间更长。DBCC INDEXDEFRAG比其他方法的确有好处的是在其他过程访问索引时也能进行碎片整理,不会引起其他方法的阻塞问题。
Ⅳ 逐步讲解 Oracle数据库碎片如何整理
对于系统管理员来讲,如何保证网络稳定运行,如何提高数据库性能,使其更加安全高效,就显得尤为重要。作为影响数据库性能的一大因素 -- 数据库碎片,应当引起 DBA 的足够重视,及时发现并整理碎片乃是 DBA 一项基本维护内容。 1、碎片是如何产生的 当生成一个数据库时,它会分成称为表空间( Tablespace )的多个逻辑段( Segment ),如系统(System)表空间 , 临时(Temporary)表空间等。一个表空间可以包含多个数据范围(Extent)和一个或多个自由范围块,即自由空间(Free Space)。 表空间、段、范围、自由空间的逻辑关系如下: 当表空间中生成一个段时,将从表空间有效自由空间中为这个段的初始范围分配空间。在这些初始范围充满数据时,段会请求增加另一个范围。这样的扩展过程会一直继续下去,直到达到最大的范围值,或者在表空间中已经没有自由空间用于下一个范围。最理想的状态就是一个段的数据可被存在单一的一个范围中。这样,所有的数据存储时靠近段内其它数据,并且寻找数据可少用一些指针。但是一个段包含多个范围的情况是大量存在的,没有任何措施可以保证这些范围是相邻存储的,当要满足一个空间要求时,数据库不再合并相邻的自由范围(除非别无选择), 而是寻找表空间中最大的自由范围来使用。这样将逐渐形成越来越多的离散的、分隔的、较小的自由空间,即碎片。例如: 2、碎片对系统的影响 随着时间推移,基于数据库的应用系统的广泛使用,产生的碎片会越来越多,将对数据库有以下两点主要影响: 1)导致系统性能减弱。 如上所述,当要满足一个空间要求时,数据库将首先查找当前最大的自由范围,而 “最大”自由范围逐渐变小,要找到一个足够大的自由范围已变得越来越困难,从而导致表空间中的速度障碍,使数据库的空间分配愈发远离理想状态; 2)浪费大量的表空间。 尽管有一部分自由范围(如表空间的 pctincrease 为非 0 )将会被 SMON (系统监控)后台进程周期性地合并,但始终有一部分自由范围无法得以自动合并,浪费了大量的表空间。 3、自由范围的碎片计算 由于自由空间碎片是由几部分组成,如范围数量、最大范围尺寸等,我们可用 FSFI--Free Space Fragmentation Index (自由空间碎片索引)值来直观体现: FSFI=100*SQRT(max(extent)/sum(extents))*1/SQRT(SQRT(count(extents))) 可以看出, FSFI 的最大可能值为 100 (一个理想的单文件表空间)。随着范围的增加, FSFI 值缓慢下降,而随着最大范围尺寸的减少, FSFI 值会迅速下降。 下面的脚本可以用来计算 FSFI 值: rem FSFI Value Compute rem fsfi.sql column FSFI format 999,99 select tablespace_name,sqrt(max(blocks)/sum(blocks))* (100/sqrt(sqrt(count(blocks)))) FSFI from dba_free_space group by tablespace_name order by 1; spool fsfi.rep; / spool off;比如,在某数据库运行脚本 fsfi.sql, 得到以下 FSFI 值: TABLESPACE_NAME FSFI ------------------------------------- RBS 74.06 SYSTEM 100.00 TEMP 22.82 TOOLS 75.79 USERS 100.00 USER_TOOLS 100.00 YDCX_DATA 47.34 YDCX_IDX 57.19 YDJF_DATA 33.80 YDJF_IDX 75.55统计出了数据库的 FSFI 值,就可以把它作为一个可比参数。在一个有着足够有效自由空间,且FSFI 值超过 30 的表空间中,很少会遇见有效自由空间的问题。当一个空间将要接近可比参数时,就需要做碎片整理了。 4、自由范围的碎片整理1)表空间的 pctincrease 值为非 0。 可以将表空间的缺省存储参数 pctincrease 改为非 0 。一般将其设为 1 ,如: alter tablespace temp default storage(pctincrease 1);这样SMON 便会将自由范围自动合并。也可以手工合并自由范围: alter tablespace temp coalesce。 5、段的碎片整理我们知道,段由范围组成。在有些情况下,有必要对段的碎片进行整理。要查看段的有关信息,可查看数据字典 dba_segments ,范围的信息可查看数据字典 dba_extents 。如果段的碎片过多, 将其数据压缩到一个范围的最简单方法便是用正确的存储参数将这个段重建,然后将旧表中的数据插入到新表,同时删除旧表。这个过程可以用 Import/Export (输入 / 输出)工具来完成。 Export ()命令有一个(压缩)标志,这个标志在读表时会引发 Export 确定该表所分配的物理空间量,它会向输出转储文件写入一个新的初始化存储参数 -- 等于全部所分配空间。若这个表关闭, 则使用 Import ()工具重新生成。这样,它的数据会放入一个新的、较大的初始段中。例如: exp user/password file=exp.dmp compress=Y grants=Y indexes=Y tables=(table1,table2);若输出成功,则从库中删除已输出的表,然后从输出转储文件中输入表: imp user/password file=exp.dmp commit=Y buffer=64000 full=Y 这种方法可用于整个数据库。 以上简单分析了 Oracle 数据库碎片的产生、计算方法及整理,仅供参考。数据库的性能优化是一项技术含量高,同时又需要有足够耐心、认真细致的工作。 对数据库碎片的一点探讨, 下面是一种如何自动处理表空间碎片的代码,希望对上大家看上文有用 Coalesce Tablespace Automatically This technique comes from Sandeep Naik, a database administrator for GSXXI, Inc. in New York City, New York Here is a handy script which can be scheled to automatically run and coalesces the tablespaces. This script is designed to run in NT but can be run in any operating system by slight modifications in the path where the file spools from the SQLPLUS environment. It assumes that the user who runs the script has priviledges to view the data dictionary. Start of code -------------------------------------- sqlplus / prompt this script will coalesce the tablespace automatically set verify off; set termout off; set head off; spool c: empcoalesce.log select alter tablespace ||TABLESPACE_NAME|| coalesce ; from DBA_FREE_SPACE_COALESCED where PERCENT_EXTENTS_COALESCED
Ⅳ 为什么sql server数据库索引碎片整理
本文需要你对索引和SQL中数据的存储方式有一定了解
在SQL Server中,存储数据的最小单位是页,每一页所能容纳的数据为8060字节.而页的组织方式是通过B树结构(表上没有聚集索引则为堆结构,不在本文讨论之列)如下图:
在聚集索引B树中,只有叶子节点实际存储数据,而其他根节点和中间节点仅仅用于存放查找叶子节点的数据.
每一个叶子节点为一页,每页是不可分割的. 而SQL Server向每个页内存储数据的最小单位是表的行(Row).当叶子节点中新插入的行或更新的行使得叶子节点无法容纳当前更新或者插入的行时,分页就产生了.在分页的过程中,就会产生碎片.
理解外部碎片
首先,理解外部碎片的这个“外”是相对页面来说的。外部碎片指的是由于分页而产生的碎片.比如,我想在现有的聚集索引中插入一行,这行正好导致现有的页空间无法满足容纳新的行。从而导致了分页:
因为在SQL SERVER中,新的页是随着数据的增长不断产生的,而聚集索引要求行之间连续,所以很多情况下分页后和原来的页在磁盘上并不连续.
Ⅵ 数据库存储空间中碎片产生的原因 及如何回收碎片
以MySQL为例,碎片的存在十分影响性能
MySQL 的碎片是 MySQL 运维过程中比较常见的问题,碎片的存在十分影响数据库的性能,本文将对 MySQL 碎片进行一次讲解。
判断方法:
MySQL 的碎片是否产生,通过查看
show table status from table_nameG;
这个命令中 Data_free 字段,如果该字段不为 0,则产生了数据碎片。
产生的原因:
1. 经常进行 delete 操作
经常进行 delete 操作,产生空白空间,如果进行新的插入操作,MySQL将尝试利用这些留空的区域,但仍然无法将其彻底占用,久而久之就产生了碎片;
演示:
创建一张表,往里面插入数据,进行一个带有 where 条件或者 limit 的 delete 操作,删除前后对比一下 Data_free 的变化。
删除前:
Data_free 不为 0,说明有碎片;
2. update 更新
update 更新可变长度的字段(例如 varchar 类型),将长的字符串更新成短的。之前存储的内容长,后来存储是短的,即使后来插入新数据,那么有一些空白区域还是没能有效利用的。
演示:
创建一张表,往里面插入一条数据,进行一个 update 操作,前后对比一下 Data_free 的变化。
CREATE TABLE `t1` ( `k` varchar(3000) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
更新语句:update t1 set k='aaa';
更新前长度:223 Data_free:0
更新后长度:3 Data_free:204
Data_free 不为 0,说明有碎片;
产生影响:
1. 由于碎片空间是不连续的,导致这些空间不能充分被利用;
2. 由于碎片的存在,导致数据库的磁盘 I/O 操作变成离散随机读写,加重了磁盘 I/O 的负担。
清理办法:
MyISAM:optimize table 表名;(OPTIMIZE 可以整理数据文件,并重排索引)
Innodb:
- select count(*) from test.twitter_11;
1. ALTER TABLE tablename ENGINE=InnoDB;(重建表存储引擎,重新组织数据)
2. 进行一次数据的导入导出
碎片清理的性能对比:
引用我之前一个生产库的数据,对比一下清理前后的差异。
SQL执行速度:
修改前:1 row in set (7.37 sec)
修改后:1 row in set (1.28 sec)
结论:
通过对比,可以看到碎片清理前后,节省了很多空间,SQL执行效率更快。所以,在日常运维工作中,应对碎片进行定期清理,保证数据库有稳定的性能。