首页 > 数据库 >Found a misplaced row,分区表修复MYSQL

Found a misplaced row,分区表修复MYSQL

时间:2023-08-13 17:33:39浏览次数:36  
标签:01 06 2014 test 分区表 sbtest MYSQL date Found

在MySQL中,分区表的数据被分隔到不同的表空间中,但仍被视为单个表。在处理大量数据集的某些情况下,分区可能是一种有用的方法。在分区表中删除庞大的数据集可以加快速度,但是如果处理不当,它可能会把数据放在表的不对应的位置中。

测试环境:mysql 8.0.30

建表

master [localhost:22031] {msandbox} (test) > create table sbtest (
    -> id bigint not null,
    -> age int not null,
    -> from_date date not null,
    -> to_date date not null,
    -> primary key (id,from_date)
    -> )
    -> partition by range columns(from_date)
    -> (PARTITION p01 VALUES LESS THAN ('2014-12-31') ,
    -> PARTITION p02 VALUES LESS THAN ('2015-12-31') ,
    -> PARTITION p03 VALUES LESS THAN ('2016-12-31') ,
    -> PARTITION p04 VALUES LESS THAN ('2017-12-31') ,
    -> PARTITION p05 VALUES LESS THAN ('2018-12-31') ,
    -> PARTITION p06 VALUES LESS THAN ('2019-12-31') ,
    -> PARTITION p07 VALUES LESS THAN ('2020-12-31') ,
    -> PARTITION p08 VALUES LESS THAN ('2021-12-31') ,
    -> PARTITION p09 VALUES LESS THAN ('2022-12-31') ,
    -> PARTITION p10 VALUES LESS THAN (MAXVALUE) );
Query OK, 0 rows affected (0.05 sec)
create table sbtest_ex_p20(
id bigint not null,
age int not null,
from_date date not null,
to_date date not null,
primary key (id,from_date)
);

在大数据量的情况下,为了更快的替换分区数据,我们会执行如下操作

master [localhost:22031] {msandbox} (test) > ALTER TABLE sbtest EXCHANGE PARTITION p08 WITH TABLE sbtest_ex_p20 WITHOUT VALIDATION;
Query OK, 0 rows affected (0.02 sec)

现在查表的总数据。

master [localhost:22031] {msandbox} (test) > select * from sbtest ;
+----+-----+------------+------------+
| id | age | from_date  | to_date    |
+----+-----+------------+------------+
|  1 |  10 | 2014-06-01 | 2014-06-01 |
|  2 |  20 | 2015-06-01 | 2015-06-01 |
|  3 |  30 | 2016-06-01 | 2016-06-01 |
|  4 |  40 | 2017-06-01 | 2014-06-01 |
|  5 |  50 | 2018-06-01 | 2014-06-01 |
|  6 |  40 | 2019-06-01 | 2014-06-01 |
|  7 |  50 | 2020-06-01 | 2014-06-01 |
|  8 |  40 | 2021-06-01 | 2014-06-01 |
|  9 |  50 | 2022-06-01 | 2014-06-01 |
| 10 |  50 | 2023-06-01 | 2014-06-01 |
| 11 |  50 | 2023-05-01 | 2014-06-01 |
+----+-----+------------+------------+
11 rows in set (0.00 sec)

当按条件查询时:

master [localhost:22031] {msandbox} (test) > select * from sbtest where id=5 and from_date='2018-06-01';
Empty set (0.00 sec)

而明明全表查询的时候有ID=5 from_date='2018-06-01'的数据,根据条件查询确没有,再看一下执行计划

master [localhost:22031] {msandbox} (test) > explain select * from sbtest where id=5 and from_date='2018-06-01';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | no matching row in const table |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
1 row in set, 1 warning (0.01 sec)

执行计划显示no matching row in const table。

这种结果是因为在做表交换分区的时候用了WITHOUT VALIDATION,不加这个选项时,分区交换是会报错的。那出现这种分区数据不在对应分区表中如可解决呢。可以有2种方法。

第一种:check table;

master [localhost:22031] {msandbox} (test) > check table sbtest;
+-------------+-------+----------+-------------------------------------------------------------------------------------+
| Table       | Op    | Msg_type | Msg_text                                                                            |
+-------------+-------+----------+-------------------------------------------------------------------------------------+
| test.sbtest | check | error    | Found a misplaced row in part 7 should be in part 0:
 from_date:2014-06-01          |
| test.sbtest | check | error    | Partition p08 returned error                                                        |
| test.sbtest | check | error    | Table upgrade required. Please do "REPAIR TABLE `sbtest`" or dump/reload to fix it! |
+-------------+-------+----------+-------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

按照提示方案解决

master [localhost:22031] {msandbox} (test) > REPAIR TABLE `sbtest`;
+-------------+--------+----------+-------------------------+
| Table       | Op     | Msg_type | Msg_text                |
+-------------+--------+----------+-------------------------+
| test.sbtest | repair | warning  | Moved 10 misplaced rows |
| test.sbtest | repair | status   | OK                      |
+-------------+--------+----------+-------------------------+
2 rows in set (0.00 sec)

再执行查询看看

master [localhost:22031] {msandbox} (test) > select * from sbtest where id=5 and from_date='2018-06-01';
+----+-----+------------+------------+
| id | age | from_date  | to_date    |
+----+-----+------------+------------+
|  5 |  50 | 2018-06-01 | 2014-06-01 |
+----+-----+------------+------------+
1 row in set (0.00 sec)

查询有数据,显示正常。但是如果表的数据量很大,这个repair表操作会锁表,影响线上业务。

第二种:pt工具,最小可能影响业务。

pt-online-schema-change --execute  --alter "ENGINE=InnoDB" h=localhost,D=test,t=sbtest

相当于是重建表,这种操作锁表的时间短,建议在业务低峰执行

标签:01,06,2014,test,分区表,sbtest,MYSQL,date,Found
From: https://blog.51cto.com/u_13482808/7068076

相关文章

  • mysql在开启group_replication后,状态显示为RECOVERING,告警日志报错MY-013117、MY-0115
    问题描述:mysql在开启group_replication后,状态显示为RECOVERING,告警日志报错MY-013117、MY-011582、MY-011583,如下所示:数据库:MySQL8.0.27系统:rhel7.364位1、问题重现Slave02[(none)]>select*fromperformance_schema.replication_group_members;+-----------------------......
  • mysql在开启group_replication后,报错ERROR 3092,This member has more executed transa
    问题描述:mysql在开启group_replication后,报错ERROR3092,Thismemberhasmoreexecutedtransactionsthanthosepresentinthegroup,如下所示:数据库:MySQL8.0.27系统:rhel7.31、异常重现Slave01[(none)]>startgroup_replication;ERROR3092(HY000):Theserverisnotc......
  • pyinstaller "importlib.metadata.PackageNotFoundError"
    使用pyinstaller打包后的python程序,执行的时候出现"importlib.metadata.PackageNotFoundError"异常Traceback(mostrecentcalllast):File"main.py",line5,in<module>File"PyInstaller/loader/pyimod02_importers.py",line352,ine......
  • mysql在安装group_replication插件时,报错"version libcrypto.so.10 not defined in fi
    问题描述:mysql在安装group_replication插件时,报错"versionlibcrypto.so.10notdefinedinfilelibcrypto.so",如下所示:数据库:mysql8.0.27系统:rhel7.364位1、异常重现mysql>installplugingroup_replicationsoname'group_replication.so';ERROR1126(HY000):......
  • 一个mysql dba的成长之旅--第零章 绝处逢生:意外收到dba offer
    (本故事纯属虚构,如有雷同实属巧合)2018年的一个秋天的下午,江南理工大学图书馆一楼的宣讲会大厅人头攒动,充满了期待的氛围。这里正在举办一场国内知名互联网公司的宣讲会,吸引了众多毕业生前来倾听。小李身穿一套整洁的求职西装,手里拿着整齐的彩色简历,坐在室友旁边,全神贯注地聆听着台......
  • Go语言gorm框架MySQL实践
    gorm是一个使用Go语言编写的ORM框架。文档齐全,对开发者友好,支持主流数据库。我最近在补齐Go语言各类基础的框架和操作库的知识,终于进展到了数据库阶段,搜资料的时候基本都是推荐这个框架,可见其之流行程度。在不断尝试练习之后,总结了一些经验和使用方式,供初学者参考。在之前使用Jav......
  • 高性能MySQL 七-十六
    七、MySQL高级性能7.1分区表MySQL在创建表时使用PARTITIONBY子句定义每个分区存放的数据分区的一个主要目的是将数据按照一个较粗的力度分在不同的表中。这样做可以将相关的数据存放在一起1)分区表的原理SELECT查询:当查询一个分区表的时候,分区层先打开并锁住所有的底层表,......
  • mysql在索引定义中直接使用条件语句
    原始数据库表如下:CREATETABLE`events`(`id`int(11)unsignedNOTNULLAUTO_INCREMENT,`status`enum('on','off')COLLATEutf8_unicode_ciNOTNULLCOMMENT'开关状态',`type`enum('gas_fee_free')COLLATEutf8_unicode_ciNOTNULL......
  • mysql8默认caching_sha2_password身份验证
    发生这个问题的原因是在mysql8.0以后,caching_sha2_password是默认的身份验证插件,而不是以往的mysql_native_password。在MySQLCommandLine工具下修改mysql的默认身份验证插件即可。Theserverrequestedauthenticationmethodunknowntotheclient[caching_sha2_passw......
  • SpringBatch读取mysql数据
    1.在本地数据库创建user表建表语句:createtable`user`(`id`bigintnotnullauto_incrementcomment'主键',`name`varchar(32)defaultnullcomment'用户名',`age`intdefaultnullcomment'年龄',primarykey(id))engine=innodbde......