💫《博主介绍》:✨又是一天没白过,我是奈斯,DBA一名✨
💫《擅长领域》:✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux,也在扩展大数据方向的知识面✌️
💖💖💖大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注💖💖💖
哈喽小伙伴们,今天我们来聊一聊如何快速应对MySQL存储数据路径空间不足的问题。当我们发现数据目录所在路径空间不足时,并且发现当前目录并非逻辑卷的时候,如何快速地将数据目录迁移到新的路径。接下来,我会详细介绍如何进行这种同机迁移操作。
在本文中,我将介绍两种方式对数据目录进行迁移的方法:通过clone本地克隆数据的方式和直接使用mv命令的方式。对于想要了解clone插件原理的同学,可以参考我之前发布的文章。现在,让我们深入探讨这两种迁移方法。
大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注。
目录
方式二:通过clone本地克隆数据的方式完成同机目录迁移(只适用于8.0.17以上版本)
方式一:通过mv方式完成新路径的迁移(适用于各个版本)
MySQL异机迁移一般采用mysqldump、mysqlpump、xtrabackup、clone等工具,这些工具都会记录当时实例的gtid方便进行主从搭建等操作。
MySQL同机迁移一般情况下是为了当前目录没有规划好大小并且不是逻辑卷而进行的同机迁移。为了减少停机时间使用直接mv数据文件并且修改datadir参数即可快速完成目录更换。
注意:对于Oracle而言不能直接mv数据文件完成同机迁移,因为Oracle在启动的三个步骤中的第二步打开控制文件就会验证数据文件的路径,那么只是直接mv是不会通知控制文件的,所以需要在sqlplus中执行命令来告知数据文件路径发生变化。
(1)查看当前数据库的数据文件路径并关闭实例
mysql> show variables like '%datadir%';
[root@mgr1 3306]# service mysqld stop ---通过service的方式关闭MySQL
(2)修改数据文件路径参数指向新的逻辑卷目录
[root@mgr1 3306]# mkdir /mysql_data/
[root@mgr1 3306]# chown -R mysql:mysql /mysql_data/
[root@mgr1 3306]# mv /mysql/data/3306/data /mysql_data/ ---mv移动数据文件目录到新的逻辑卷目录
[root@mgr1 3306]# vi /mysql/data/3306/my.cnf
(3)如果是通过linux服务启动(service)还需要修改服务启动脚本
[root@mgr1 3306]# vi /etc/init.d/mysqld
修改一:目录和数据存储目录
修改二:相关目录和数据存储目录
注意:$datadir表示调用datadir的变量,所以不用修改。
(4)启动实例,验证相关目录
[root@mgr1 3306]# service mysqld start
mysql> show variables like '%datadir%';
验证:
mysql> show databases;
mysql> select table_name from information_schema.tables;
mysql> select * from ded.bak11;
mysql> select * from it.emp;
mysql> select * from it.yg;
###能查询到数据,表示数据恢复的没问题。可能存在表不能查询的情况,那么就是数据字典没有记录表的问题,需要多验证几张
方式二:通过clone本地克隆数据的方式完成同机目录迁移(只适用于8.0.17以上版本)
想要了解clone插件原理的同学,可以参考我之前发布的文章。快速通道👉MySQL篇—通过Clone插件进行本地克隆数据(第二篇,总共三篇)_yii clone 复制一条数据库的记录-CSDN博客👈
本地克隆数据的用途:
1、备份实例到本地
2、对数据目录进行迁移(本地克隆进行迁移一般情况下是为了当前目录没有规划好大小并且不是逻辑卷而进行的同机迁移,今天主要介绍这种)
本地克隆数据语法:
本地克隆操作从MySQL服务器实例中克隆数据,其中克隆操作启动到MySQL服务器实例运行的同一服务器或节点上的目录。
语法:
CLONE LOCAL DATA DIRECTORY [=] 'clone_dir'; ###用户需要有BACKUP_ADMIN权限
如何停止本地克隆:
SQL> select * from performance_schema.clone_status\G; ###克隆操作的状态
PID:Processlist ID。对应show processlist中的Id,如果要终止当前的克隆操作,执行kill processlist_id命令即可。
SQL> kill+id号;
本地克隆相关视图:
SQL> select * from performance_schema.clone_status\G; ###克隆操作的状态
PID:Processlist ID。对应show processlist中的Id,如果要终止当前的克隆操作,执行kill processlist_id命令即可。
STATE:克隆操作的状态,Not Started(克隆尚未开始),In Progress(克隆中),Completed(克隆成功),Failed(克隆失败)。如果是Failed状态,ERROR_NO,ERROR_MESSAGE会给出具体的错误编码和错误信息。
BEGIN_TIME:克隆操作开始
END_TIME:克隆结束时间。
SOURCE:Donor(源库)实例的地址。
DESTINATION:克隆目录。“LOCAL INSTANCE”代表当前实例的数据目录。
BINLOG_FILE:克隆完成后的file号
BINLOG_POSITION:file的pos点
GTID_EXECUTED:克隆的gtid点,可利用这些信息来搭建从库。
SQL> select * from performance_schema.clone_progress; ###克隆的进度信息
SQL> select
stage,
state,
cast(begin_time as DATETIME) as "START TIME",
cast(end_time as DATETIME) as "FINISH TIME",
lpad(sys.format_time(power(10,12) * (unix_timestamp(end_time) - unix_timestamp(begin_time))), 10, ' ') as DURATION,
lpad(concat(format(round(estimate/1024/1024,0), 0), "MB"), 16, ' ') as "Estimate",
case when begin_time is NULL then LPAD('%0', 7, ' ')
when estimate > 0 then
lpad(concat(round(data*100/estimate, 0), "%"), 7, ' ')
when end_time is NULL then lpad('0%', 7, ' ')
else lpad('100%', 7, ' ')
end as "Done(%)"
from performance_schema.clone_progress;
STAGE:一个克隆操作可依次细分为DROP DATA,FILE COPY,PAGE COPY,REDO COPY,FILE SYNC,RESTART,RECOVERY等7个阶段。当前阶段结束了才会开始下一个阶段。本地克隆只涉及到前五个阶段完成DROP DATA,FILE COPY,PAGE COPY,REDO COPY,FILE SYNC,远程克隆涉及到七个阶段
STATE:当前阶段的状态。有三种状态:Not Started,In Progress,Completed。
BEGIN_TIME:当前阶段的开始时间和结束时间。
END_TIME:当前阶段的开始时间和结束时间。
THREADS:当前阶段使用的并发线程数。并发线程数一般由clone_autotune_concurrency参数自动调节。默认为ON,此时该参数最大线程数受clone_max_concurrency参数控制。若设置为OFF,则并发线程数的数量将是固定的同clone_max_concurrency参数保持一致。clone_max_concurrency参数的默认值为16。
ESTIMATE:预估的数据量。
DATA:已经拷贝的数据量。
NETWORK:通过网络传输的数据量。如果是本地克隆,该列的值为0。
DATA_SPEED:当前数据拷贝的速率。注意,是当前值。
NETWORK_SPEED:当前网络传输的速率。注意,是当前值。
案例开始(通过本地克隆对数据目录进行迁移):
一、首先先安装Clone(数据克隆)插件(插件安装)
第一种方式(将插件写到参数文件):
plugin_dir=/mysql/app/mysql/lib/plugin/ ---mysql插件的默认安装位置
plugin_load="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so;mysql_clone.so" ---插件加载
第二种方式(手动安装):
mysql> INSTALL PLUGIN clone SONAME 'mysql_clone.so'; ---这种是手动在线安装插件,不需要重启,并且重启后也不会失效。
mysql> show plugins;
二、在Donor实例上创建克隆用户:
mysql> create user 'donor_clone_user'@'%' identified by '123456';
mysql> grant backup_admin on *.* to 'donor_clone_user'@'%';
三、创建clone目录(也就是迁移的目录):
[root@mysql8 ~]# mkdir /clone_dir
[root@mysql8 ~]# chown -R mysql:mysql /clone_dir
四、了解克隆数据时,对DML和DDL操作的影响
DML:不影响
mysql> insert into tb1 values (23); Query OK, 1 row affected (0.81 sec)
DDL:长期不返回,需要等到克隆完成(不过可以通过设置clone_ddl_timeout参数在克隆期间允许DDL不过会导致克隆失败,在8.0.27版本新增clone_block_ddl参数在克隆期间允许DDL同时不会导致克隆失败)
mysql> create table itdwd (id int); 无响应 为了在克隆期间允许DDL,设置clone_ddl_timeout参数为0,虽然会导致克隆失败但要保证DDL不受影响。8.0.27版本新增clone_block_ddl参数在克隆期间允许DDL同时不会导致克隆失败 mysql> set global clone_ddl_timeout=0; ---只用在recipient上设置即可,设置为0意味着克隆操作不会等待备份锁。在这种情况下,donor主库执行并发DDL操作可能导致克隆操作失败,设置为其他数值发现还是需要等到克隆完成,只有设置为0。在donor主库设置为0,还是长期不返回,还是需要等到克隆完成,所以只用在recipient从库设置为0即可
五、设置克隆期间允许DDL(为了在克隆期间允许DDL,设置clone_ddl_timeout参数为0,虽然会导致克隆失败但要保证DDL不受影响。8.0.27版本新增clone_block_ddl参数在克隆期间允许DDL同时不会导致克隆失败。这个设置可选)
mysql> set global clone_ddl_timeout=0; ---只用在recipient上设置即可,设置为0意味着克隆操作不会等待备份锁。在这种情况下,donor主库执行并发DDL操作可能导致克隆操作失败,设置为其他数值发现还是需要等到克隆完成,只有设置为0。在donor主库设置为0,还是长期不返回,还是需要等到克隆完成,所以只用在recipient从库设置为0即可
六、Clone(数据克隆)发起克隆命令
[root@slave ~]# mysql -udonor_clone_user -p123456 -S /var/lib/mysql/mysql.sock mysql> clone local data directory='/clone_dir/3306'; ###其中/clone_dir/3306是克隆目录,其需满足以下几点要求: 1、克隆目录必须是绝对路径。 2、/clone_dir必须存在,且MySQL对其有可写权限。 3、3306不能存在。
注:本地克隆只涉及到五个阶段完成DROP DATA,FILE COPY,PAGE COPY,REDO COPY,FILE SYNC,远程克隆涉及到七个阶段,也是就说本地克隆完成不会重启数据库(RESTART)和数据一致性效验(RECOVERY)
七、查看克隆操作
SQL> select * from performance_schema.clone_progress; ###克隆的进度信息
SQL> select
stage,
state,
cast(begin_time as DATETIME) as "START TIME",
cast(end_time as DATETIME) as "FINISH TIME",
lpad(sys.format_time(power(10,12) * (unix_timestamp(end_time) - unix_timestamp(begin_time))), 10, ' ') as DURATION,
lpad(concat(format(round(estimate/1024/1024,0), 0), "MB"), 16, ' ') as "Estimate",
case when begin_time is NULL then LPAD('%0', 7, ' ')
when estimate > 0 then
lpad(concat(round(data*100/estimate, 0), "%"), 7, ' ')
when end_time is NULL then lpad('0%', 7, ' ')
else lpad('100%', 7, ' ')
end as "Done(%)"
from performance_schema.clone_progress;
八、查看当前数据库的数据文件路径并关闭实例
mysql> show variables like '%datadir%';
[root@mgr1 3306]# service mysqld stop ---通过service的方式关闭MySQL
九、修改数据文件路径参数指向新的逻辑卷目录
[root@mgr1 3306]# vi /mysql/data/3306/my.cnf
十、如果是通过linux服务启动(service)还需要修改服务启动脚本
[root@mgr1 3306]# vi /etc/init.d/mysqld
修改一:目录和数据存储目录
修改二:相关目录和数据存储目录
注意:$datadir表示调用datadir的变量,所以不用修改。
十一、启动实例,验证相关目录
[root@mgr1 3306]# service mysqld start mysql> show variables like '%datadir%';
十二、验证目标库与源库的数据、对象
第一步:查看用户以及权限
mysql> select host,user from mysql.user; mysql> show grants for root@'%';
第二步:验证数据库是否恢复和备份之后创建表的数据是否恢复
mysql> show databases; mysql> select * from test04;
第三步:验证对象数量
mysql> select * from sys.schema_object_overview where db='test'; ---数据对象
mysql> select engine,count(*) from information_schema.tables group by engine; ---存储引擎分类
第四步:验证数据量:
select concat('select count(*) from ',table_schema,'.',table_name,';') from information_schema.tables where table_schema='库名';